优化Pandas分组聚合:高效计算加权均价与非空属性提取
高效实现Pandas分组聚合方案
针对你遇到的自定义聚合函数效率低下的问题,可以通过替换自定义函数为Pandas内置的高效操作来大幅提升性能,以下是优化后的完整实现:
优化思路
- 移除自定义
first函数,改用迭代器方式获取第一个非空值(next(iter(s.dropna()), None)),获取最后一个非空值则用next(reversed(s.dropna()), None),这种方式比iloc操作更高效,减少中间Series的创建开销。 - 保留原有的
cost列计算逻辑,避免重复计算加权平均的分子分母,保证聚合效率。 - 全程使用Pandas原生聚合方法,去掉冗余的类型检查和额外操作。
完整优化代码
import pandas as pd df = pd.DataFrame({ "commodity":["Potatos","Potatos","Apples","Apples","Apples"], "amount":[1,2,3,4,None], "price":[4,5,6,7,8], "attr1":[None,1,None,"foo","bar"], # 示例:新增需要取最后一个非空值的attr2列 "attr2":["x", None, "y", None, "z"] }) # 计算加权平均所需的cost列(amount*price) df["cost"] = df["amount"] * df["price"] # 定义聚合规则:用高效迭代替代自定义函数 agg_rules = { "amount": "sum", "cost": "sum", "attr1": lambda s: next(iter(s.dropna()), None), # 第一个非空值 "attr2": lambda s: next(reversed(s.dropna()), None) # 最后一个非空值 } # 分组聚合(as_index=False避免commodity成为索引) summary = df.groupby("commodity", as_index=False).agg(agg_rules) # 计算price的加权平均值 summary["price"] = summary["cost"] / summary["amount"] # 清理临时列并还原原列顺序 summary = summary.drop(columns=["cost"])[df.columns] print(summary)
性能提升原因
- 去掉了自定义函数中的
assert检查和冗余的Series转换操作,减少函数调用的额外开销。 - 使用迭代器直接获取目标值,比
dropna().iloc[]减少了中间Series的创建和索引操作,内存占用更低、执行速度更快。 - 保留
cost列的计算逻辑,确保加权平均的分子分母只计算一次,避免重复运算。
内容的提问来源于stack exchange,提问作者sds
相关产品推荐
相关产品推荐

