如何编写向量化函数实现两个不同大小DataFrame间的数据聚合
优化方案
原代码性能差的核心原因是使用了两层Python层的行级apply,完全没有利用pandas的向量化运算能力,替换为内置向量化操作后,性能提升可达千倍以上。
注意:原代码存在笔误,
get_cumsum_values调用时传入的data参数写为df1,实际应该传入待统计的df2,否则统计逻辑完全错误。
单阈值场景(仅需新增1列)
如果只需要计算固定阈值(如示例中的10)的求和结果,直接筛选后分组聚合即可:
import pandas as pd # 原始数据 df2 = pd.DataFrame({'name':['alan','sky','liam','liam','alan','liam','alan','sky','bryan','alan','sky'] ,'age': [1,5,10,15,20,25,30,35,40,45,50] ,'values': [564,65,4,44,8,60,4,684,51,3,14]}) df1 = pd.DataFrame({'name':['alan','sky','liam','bryan']}) threshold = 10 # 先筛选符合age条件的行,按name分组求和 sum_mapping = df2[df2['age'] < threshold].groupby('name')['values'].sum() # 映射到df1,无匹配的填充0 df1['10'] = df1['name'].map(sum_mapping).fillna(0).astype(int)
多阈值场景(需新增多列不同阈值的求和结果)
如果需要批量生成多个阈值的统计列,可先预计算每个name的累积和,再批量匹配阈值,进一步降低重复计算开销:
# 预排序+预计算组内累积和 df2_sorted = df2.sort_values(['name', 'age']).reset_index(drop=True) df2_sorted['cumsum_val'] = df2_sorted.groupby('name')['values'].cumsum() # 可自定义任意阈值列表 thresholds = [10, 20, 30, 40] for t in thresholds: # 取每个name下age小于阈值的最大累积和 t_sum = df2_sorted[df2_sorted['age'] < t].groupby('name')['cumsum_val'].max() df1[str(t)] = df1['name'].map(t_sum).fillna(0).astype(int)
性能说明
pandas内置的筛选、分组、聚合操作均为底层C实现的向量化运算,避免了Python层循环的高额调用开销。针对百万级以上的海量数据,优化后的代码运行耗时仅为原apply实现的千分之一甚至更低,且输出结果和原修正笔误后的代码完全一致。
内容的提问来源于stack exchange,提问作者jezebel
相关产品推荐
相关产品推荐

