pandas DataFrame append方法效率低下原因及替代方案咨询
问题根源
- pandas的DataFrame底层是固定大小的连续内存结构,每次调用
append都会重新申请整个新表的内存、复制全部旧数据+新数据,循环100万次的时间复杂度是O(n²),数据量越大耗时增长越快,这是代码跑几个小时都跑不完的核心原因。 - 额外性能损耗点:初始化的DataFrame列是
('Open','High','Low','Close','Avg20'),但append的字典里是Avg9,每次append都需要做列对齐、填充空值,进一步拖慢速度。
另外从pandas 1.4版本开始df.append方法已经被官方废弃,不再推荐使用。
最优替代方案
方案1:先存列表再一次性转DataFrame(性能最高,推荐)
列表的append是均摊O(1)的操作,先把所有行数据存在列表里,最后只做一次DataFrame转换,100万行数据总耗时通常不会超过1秒。
优化后的代码示例:
import pandas as pd import datetime import random row_list = [] start = datetime.datetime.now() for i in range(1000000): if i % 10000 == 0: print(i/1000000*100 , '%completed.') # 直接把行字典存在列表里 row_list.append({'Open':random.random(), 'High':random.random(), 'Low':random.random(), 'Close':random.random(),'Avg9':random.random()}) # 最后一次性转DataFrame data = pd.DataFrame(row_list) end = datetime.datetime.now() print(start, end)
方案2:流式数据分批合并
如果数据是逐批生成的流式数据,没法一次性拿到全部数据,可以每攒够一批(比如1000/10000行)转成一个小DataFrame,最后用pd.concat一次性合并所有小DataFrame,避免逐行操作。
注意:不要在循环里反复调用pd.concat,和append一样会产生O(n²)的时间复杂度。
内容的提问来源于stack exchange,提问作者Sun Jar
相关产品推荐
相关产品推荐

