Pandas中如何用apply/向量化操作高效将DataFrame转为JSON列
百万级数据高效实现方案
核心性能瓶颈
原实现运行速度慢的核心原因:
- 嵌套三层Python循环,每轮groupby都会生成全新的子DataFrame对象,内存开销大
- 使用
iterrows逐行读取单元格标量值,是pandas中效率最低的操作之一 - 逐次构建字典、逐次转JSON,全流程Python解释器执行占比极高,没有利用pandas底层C实现的向量化能力
向量化优化实现
整体思路是把逐行操作全部替换为整列批量处理,把循环次数从“全表百万行级别”降低到“(id, days)组合的千/百级别”,可实现10-100倍的性能提升,完整可运行代码如下:
import pandas as pd import json # 第一步:向量化生成复合键(替代逐行f-string拼接) # 整列字符串拼接是C实现的,速度比逐行f-string快几个量级 df['composite_key'] = df['type'].astype(str) + df['delta'].astype(str) # 第二步:定义组级别的结构构建逻辑(无逐行遍历) def build_day_struct(group): # 对单个(id, days)分组做一次字典构建,不再逐行循环 return { "A": dict(zip(group['composite_key'], group['A'])), "B": dict(zip(group['composite_key'], group['B'])) } # 第三步:批量分组聚合(pandas底层C实现,无额外Python层循环开销) agg_df = df.groupby(['id', 'days'], as_index=False).apply( build_day_struct, include_groups=False # 避免传入分组依据列到聚合函数,减少内存占用;pandas版本低于2.2时可删除该参数 ) agg_df.columns = ['id', 'days', 'day_content'] # 第四步:生成目标列名(day_xx格式),透视成宽表 agg_df['col_label'] = 'day_' + agg_df['days'].astype(str) result_df = agg_df.pivot( index='id', columns='col_label', values='day_content' ).reset_index() # 第五步:整列批量转JSON字符串,避免逐行序列化 day_cols = [c for c in result_df.columns if c.startswith('day_')] for col in day_cols: result_df[col] = result_df[col].map(lambda x: json.dumps(x, ensure_ascii=False))
优化说明
- 全流程没有任何
iterrows调用,所有逐行操作全部替换为向量化的整列字符串拼接、组内值配对 - 循环执行次数从百万行级别,降低为每个(id, days)分组执行一次字典构建,循环量缩减为原方案的1%甚至更低
- 分组、透视、JSON序列化全部使用pandas的批量处理能力,减少Python解释器的介入开销
- 百万行规模数据通常可在数秒内完成处理,远快于原逐行遍历方案
内容的提问来源于stack exchange,提问作者ThomasBecker
相关产品推荐
相关产品推荐

