如何高效遍历数组行并将结果写入Pandas DataFrame?
针对Pandas+Numpy大数据集的高效计算与内存优化方案
一、替换逐行迭代的向量化优化
你的原代码通过两次逐行循环计算累积倍数,这种方式在大数据集下效率极低——Python循环本身开销大,且无法利用Numpy的CPU并行优化。可以用Numpy向量化操作完全替代循环,大幅提升计算速度:
原逻辑等价于先计算相邻行的比值,再对每列做累积乘积,用np.cumprod(累积乘积函数)可一步完成:
import pandas as pd import numpy as np # 初始化数据 data = [[2,2,2],[2,2.1,2.2],[4,4,4],[6,6,6],[12,12,12]] columns = ['N1','N2','N3'] index = ['yaba','daba','doo','doo2','doo3'] df1 = pd.DataFrame(data, columns=columns, index=index) # 转换为Numpy数组 A = df1.to_numpy() # 向量化计算替代两次循环 B = np.ones_like(A, dtype=float) # 计算从第二行开始,每行与上一行的比值 B[1:] = A[1:] / A[:-1] # 对每列做累积乘积,得到最终结果 B = np.cumprod(B, axis=0)
效率提升原因
- Numpy向量化操作基于C语言实现,避免了Python循环的解释器开销
- 自动利用CPU的SIMD并行指令,大数据集下速度可提升几十到上百倍
- 内存使用更紧凑,无需循环中频繁的数组元素赋值操作
二、直接写入现有DataFrame的内存优化
原代码创建df2再复制给df1的方式,会额外占用一倍内存(同时存储df1和df2)。可以直接将Numpy数组写入现有DataFrame的内存空间,无需创建新对象:
方法1:直接赋值给values属性
# 直接将B写入df1,无额外内存开销 df1.values[:] = B
方法2:用.loc批量赋值
若需确保索引和列对齐(数组形状与DataFrame完全匹配时,两种方法效果一致),也可使用:
df1.loc[:] = B
操作后原df1的内存空间被直接覆盖,无需手动删除df2——Python垃圾回收会自动处理不再使用的数组。
完整优化后代码
import pandas as pd import numpy as np data = [[2,2,2],[2,2.1,2.2],[4,4,4],[6,6,6],[12,12,12]] columns = ['N1','N2','N3'] index = ['yaba','daba','doo','doo2','doo3'] df1 = pd.DataFrame(data, columns=columns, index=index) A = df1.to_numpy() # 向量化计算 B = np.ones_like(A, dtype=float) B[1:] = A[1:] / A[:-1] B = np.cumprod(B, axis=0) # 直接写入现有DataFrame df1.values[:] = B print(df1)
输出结果与原代码完全一致:
N1 N2 N3 yaba 1.0 1.00 1.0 daba 1.0 1.05 1.1 doo 2.0 2.00 2.0 doo2 3.0 3.00 3.0 doo3 6.0 6.00 6.0
内容的提问来源于stack exchange,提问作者chirob
相关产品推荐
相关产品推荐

