如何提升从JSON列表构建pandas DataFrame的效率
效率低下原因
逐行调用df.append()性能极差的核心逻辑是:pandas的append方法每次执行都会完整复制现有DataFrame的全部数据生成新对象,随着行数增长,复制开销会呈非线性上涨,处理百万行数据时会产生巨量无效IO和内存操作。
最高效实现方案
先把所有待入库的字典数据归集到原生Python列表中,最后一次性传入pandas的DataFrame构造函数即可。原生列表的append是预分配内存的O(1)操作,没有全量复制开销,配合pandas批量构造的优化,处理180万行数据通常仅需数秒到十几秒,相比原写法性能提升可达百倍以上。
优化后完整代码
import pandas as pd import time start = time.perf_counter() data_collection = [] row_count = 0 # 仅做原生列表的数据归集,不触发DataFrame操作 for batch in json_file: for item in batch['data']: data_collection.append(item['data']) row_count += 1 # 批量构造DataFrame df = pd.DataFrame(data_collection) end = time.perf_counter() print(f"共处理{row_count}行数据,总耗时{end - start:.2f}秒")
大内存场景可选优化
如果180万行数据归集后内存占用过高,可以采用分块构造+一次性合并的方案,进一步降低内存峰值:
- 每归集10万-20万行数据就构造一个子DataFrame存入块列表,清空临时归集列表
- 所有块处理完成后,调用
pd.concat()一次性合并所有子DataFrame - 禁止逐行或千行级小批量调用
append/concat,否则仍会产生高额复制开销
分块实现参考代码:
import pandas as pd import time start = time.perf_counter() chunk_size = 150000 # 可根据本机内存调整块大小 chunks = [] temp_chunk = [] row_count = 0 for batch in json_file: for item in batch['data']: temp_chunk.append(item['data']) row_count += 1 # 达到块大小就生成子DataFrame if len(temp_chunk) >= chunk_size: chunks.append(pd.DataFrame(temp_chunk)) temp_chunk.clear() # 处理最后剩余的不足块大小的数据 if temp_chunk: chunks.append(pd.DataFrame(temp_chunk)) # 一次性合并所有块 df = pd.concat(chunks, ignore_index=True) end = time.perf_counter() print(f"共处理{row_count}行数据,总耗时{end - start:.2f}秒")
补充:你原有代码的计时逻辑存在语法错误,
t2 = time.perf_counter未加执行括号,实际存储的是函数对象而非时间戳,统计出的耗时结果完全无效,上述代码已修正该问题。
内容的提问来源于stack exchange,提问作者Shawn N
相关产品推荐
相关产品推荐

