Pandas中无需循环高效计算列逐行累计值的实现方案
逐行累计求和的高效实现方案
你要实现的逐行累计求和逻辑,完全不需要手写循环,调用pandas内置的向量化方法即可,在数千行乃至百万行规模的数据集上,运行速度会比iterrows()循环快100~1000倍。
核心实现仅需一行代码:
hh['z'] = hh['D'].cumsum()
逻辑匹配说明
cumsum()的运算规则和你现有循环的计算逻辑、递推公式完全对齐:
- 你之前的循环从初始值
x=0开始累加,第一行的z值直接取当前行D列的原始值 - 从第二行开始,每行的
z值等于上一行的累计值加上当前行D列的数值,完全对应你写的Z2 = z1 + D2、Z3 = z2 + D3的递推规则
和旧代码的输出格式对齐
你原来的循环因为逐行做加法赋值,最终生成的z列是浮点类型,如果需要完全匹配旧代码的输出格式,只需要补充类型转换即可:
hh['z'] = hh['D'].cumsum().astype(float)
运行后得到的结果和你贴的循环执行输出完全一致:
A B C D z 0 7 8 7 9 9.0 1 3 8 7 7 16.0 2 0 4 4 3 19.0 3 7 5 8 3 22.0 4 2 1 6 1 23.0 5 2 0 2 7 30.0 6 5 4 2 7 37.0 7 3 4 0 7 44.0 8 1 3 9 2 46.0 9 9 9 0 8 54.0
原循环性能差的原因
iterrows()方法在运行时会逐行生成独立的Series对象,配合at方法逐行赋值的操作会产生大量Python解释层的开销,完全没有用到pandas底层优化过的C级向量化运算,因此在数千行规模的数据集上就会出现明显的运行延迟。
可选扩展能力
- 自定义累计初始值:如果需要从非0的固定值开始累加,只需要在累计结果上加上对应值即可,比如初始值为100的场景:
hh['z'] = 100 + hh['D'].cumsum()
- 缺失值适配:如果D列存在空值,可以通过
skipna参数控制累计逻辑:- 默认
skipna=True:计算时自动跳过缺失值,仅累加非空的D列值 - 传入
skipna=False:遇到缺失值时,后续所有行的累计值会变为NaN,实现累计中断的效果
- 默认
内容的提问来源于stack exchange,提问作者Grantx
相关产品推荐
相关产品推荐

