You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中无需iterrows实现递归生成依赖前一行的新列?

不用iterrows实现递归生成新列的Pandas实用技巧

嘿,这个问题我太熟悉了!你的递归公式 NewColumnₙ = OldColumnₙ * 0.6 + NewColumnₙ₋₁ * 0.4 其实刚好对应指数加权移动平均(EWMA),Pandas内置了专门的工具来处理这类问题,完全不用手动写循环或者用慢得离谱的iterrows。下面给你几种高效的实现方式,从最简洁到最灵活的都有:

方法1:直接用Pandas内置的ewm函数(首推!)

这个公式里,当前值权重0.6、前结果权重0.4的逻辑,完美匹配EWMA的递归计算规则。你只需要指定alpha=0.6(α就是当前值的权重),再加上adjust=False强制用递归式计算,一行代码就能搞定:

import pandas as pd

# 假设你的DataFrame是df,旧列叫'OldColumn'
df['NewColumn'] = df['OldColumn'].ewm(alpha=0.6, adjust=False).mean()

这里的adjust=False一定要加,它会让Pandas用你想要的递归逻辑(NewColumnₙ = α*OldColumnₙ + (1-α)*NewColumnₙ₋₁),而不是默认的整体加权平均公式,完全贴合你的需求。

方法2:用Numpy做矢量化累积计算

如果之后你需要自定义更复杂的递归逻辑(不是标准EWMA那种),可以用Numpy的cumprod和cumsum实现纯矢量化计算,彻底避开循环:

import numpy as np

alpha = 0.6
beta = 0.4  # 也就是1 - alpha

# 生成beta的幂次权重序列
weights = beta ** np.arange(len(df))
# 计算加权后的旧列值
weighted_old = df['OldColumn'] * alpha * weights
# 累积求和后除以对应权重,得到递归结果
df['NewColumn'] = weighted_old.cumsum() / weights

这种方法没有任何显式循环,效率比iterrows高N倍,适合自定义递归公式的场景。

方法3:用Numba加速自定义递归函数

要是你的递归逻辑特别复杂,没法用矢量化方法表达,那试试Numba——它能把Python循环编译成机器码,速度接近原生C,比iterrows快几个数量级:

from numba import jit

@jit(nopython=True)
def recursive_calc(old_col, alpha, beta):
    n = len(old_col)
    new_col = np.empty(n)
    # 这里假设第一行的NewColumn等于OldColumn,你可以根据实际需求修改初始值
    new_col[0] = old_col[0]
    for i in range(1, n):
        new_col[i] = alpha * old_col[i] + beta * new_col[i-1]
    return new_col

# 注意要传入numpy数组,比直接传Series更快
df['NewColumn'] = recursive_calc(df['OldColumn'].values, 0.6, 0.4)

关于类似R中purrr的工具

Pandas本身没有完全对标purrr的工具包,但它的矢量化操作(比如apply、transform、ewm这些)加上Numpy的支持,已经能覆盖大部分purrr的场景。另外你可以看看pandas-flavor这个库,它允许你给Pandas添加自定义方法,有点类似purrr的管道风格,但核心还是靠Pandas和Numpy的矢量化能力提升效率。

最后再啰嗦一句:千万别用iterrows,逐行迭代效率极低,大数据集下会慢到让你怀疑人生。上面的方法要么是内置优化的函数,要么是矢量化/编译后的逻辑,性能提升不是一点半点。

内容的提问来源于stack exchange,提问作者Byron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:02:53