优化Pandas数据分析代码性能:百万级数据处理卡顿求助
优化百万级数据下的分组标记代码
原代码核心问题
- 逐行循环的低效性:遍历每行索引并重复执行布尔索引筛选,时间复杂度为O(n²),百万级数据下会重复执行百万次全表扫描,完全无法忍受。
- 重复数据修改:每次匹配到组后都通过
loc修改切片,触发多次DataFrame复制,大幅降低性能。 - 拼写错误:代码中
cconciliation_df_temp是笔误,应为conciliation_df_temp。
优化方案(向量化分组操作)
利用pandas的内置分组功能完成逻辑,全程避免逐行循环,时间复杂度降至O(n),百万级数据可在短时间内完成处理。
方案一:分组筛选+合并映射
# 复制原数据(无需保留原数据可省略copy) conciliation_df_temp = conciliation_df.copy() # 初始化DOC_COMP列为空字符串 conciliation_df_temp['DOC_COMP'] = "" # 按EMP、RAZAO、ATRIB分组,计算每组MONTCALC求和并保留两位小数 grouped_sum = conciliation_df_temp.groupby(['EMP', 'RAZAO', 'ATRIB'])['MONTCALC'].sum().round(2) # 筛选求和为0的组,分配递增ID valid_groups = grouped_sum[grouped_sum == 0].reset_index() valid_groups['DOC_COMP'] = range(1, len(valid_groups) + 1) # 将ID映射回原DataFrame conciliation_df_temp = conciliation_df_temp.merge( valid_groups, on=['EMP', 'RAZAO', 'ATRIB'], how='left' ) # 合并后处理DOC_COMP列:用匹配到的ID替换空值,未匹配的保留原空字符串 conciliation_df_temp['DOC_COMP'] = conciliation_df_temp['DOC_COMP_y'].fillna(conciliation_df_temp['DOC_COMP_x']) conciliation_df_temp = conciliation_df_temp.drop(columns=['DOC_COMP_x', 'DOC_COMP_y'])
方案二:transform+字典映射
conciliation_df_temp = conciliation_df.copy() conciliation_df_temp['DOC_COMP'] = "" # 用transform计算每行所在组的求和值(保留两位小数) group_sum = conciliation_df_temp.groupby(['EMP', 'RAZAO', 'ATRIB'])['MONTCALC'].transform( lambda x: round(x.sum(), 2) ) # 提取所有求和为0的唯一组,生成组-ID映射字典 valid_groups = conciliation_df_temp[group_sum == 0][['EMP', 'RAZAO', 'ATRIB']].drop_duplicates() group_id_map = {tuple(row): idx+1 for idx, row in valid_groups.iterrows()} # 给每行分配对应ID,未匹配组保持空字符串 conciliation_df_temp['DOC_COMP'] = conciliation_df_temp.apply( lambda r: group_id_map.get((r['EMP'], r['RAZAO'], r['ATRIB']), ""), axis=1 )
关键优化点
- 仅执行一次分组计算,避免重复全表扫描
- 用向量化操作替代逐行循环,充分利用pandas的底层优化
- 减少DataFrame的重复修改,降低内存开销
内容的提问来源于stack exchange,提问作者Rafael Rodriguero
相关产品推荐
相关产品推荐

