基于DataFrame现有列创建新列遇PerformanceWarning问题求助
解决Pandas循环创建移位列的性能问题
你的问题出在多次循环插入列导致DataFrame内存碎片化,以及后续错误的concat方式(每次循环都合并整个DataFrame,带来O(n²)的时间开销)。下面是高效的解决方案:
正确实现方式:一次性生成所有移位列再合并
不要循环给原DataFrame逐个加列,而是先一次性生成所有需要的移位列,再通过一次pd.concat完成合并,从根源避免碎片化和重复复制的问题:
import pandas as pd x = range(1, 10000) df = pd.DataFrame({'QObs': x}) # 用字典推导式一次性生成所有移位列的DataFrame shifted_df = pd.DataFrame( {f'QObs{i}': df['QObs'].shift(i) for i in range(1, 120)} ) # 一次性合并原DataFrame和移位列DataFrame df = pd.concat([df, shifted_df], axis=1)
为什么你的代码慢?
- 最初的循环:每次
df[nameQ] = df['QObs'].shift(i)都会触发DataFrame的insert操作,多次插入会让内存中的DataFrame变得碎片化,Pandas需要频繁重新分配内存,导致性能下降并触发警告。 - 你尝试的concat版本:每次循环都执行
pd.concat([df, df_new], axis=1),而df会随着循环逐渐变大,每次合并都要复制整个现有数据,循环119次后,时间开销会呈指数级增长。
另一种等价实现(列表推导式)
如果更习惯用列表处理,也可以用列表生成所有移位后的Series,再一次性合并:
import pandas as pd x = range(1, 10000) df = pd.DataFrame({'QObs': x}) # 生成所有重命名后的移位Series shifted_series = [df['QObs'].shift(i).rename(f'QObs{i}') for i in range(1, 120)] # 合并原DataFrame和所有移位Series df = pd.concat([df] + shifted_series, axis=1)
这两种方式都能高效完成需求,不会触发性能警告,运行速度远快于你之前的实现。
内容的提问来源于stack exchange,提问作者Rodolfo
相关产品推荐
相关产品推荐

