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

如何用Pandas高效实现DataFrame列的递推乘积填充(非显式循环)

问题描述

现有如下Pandas DataFrame:

date     |     colA     |       ColB
------------------------------------
1971-10-01   0.002451            NaN
1971-11-01   0.002445            NaN
1971-12-01   0.002439            NaN
1972-01-01   0.002433            NaN
1972-02-01   0.004854            NaN
1972-03-01   0.000000    250341816.0
1972-04-01   0.002415            NaN
1972-05-01   0.002410            NaN
1972-06-01   0.002404            NaN

需要将其转换为:

date     |     colA     |       ColB
------------------------------------
1971-10-01   0.002451            0
1971-11-01   0.002445            0
1971-12-01   0.002439            0
1972-01-01   0.002433            0
1972-02-01   0.004854            0
1972-03-01   0.000000    250341816.0
1972-04-01   0.002415    250946391.486
1972-05-01   0.002410    251551172.289
1972-06-01   0.002404    252155901.307

具体需求:

  • ColB中仅存在一个有效值250341816.0,其余均为NaN;
  • 将该有效值上方的所有行ColB填充为0;
  • 有效值下方的行按公式df['ColB'].iloc[i] = df['ColB'].iloc[i-1] * (1 + df['colA'].iloc[i])计算填充;
  • 要求无需显式遍历所有索引的简洁实现方法。
解决方案

可以利用Pandas的向量化操作和fillna、cumprod方法实现,无需循环遍历,步骤如下:

1. 定位有效值并填充上方NaN为0

# 找到ColB第一个非空值的索引
valid_idx = df['ColB'].first_valid_index()
# 将有效值上方的ColB空值批量替换为0
df.loc[:valid_idx, 'ColB'] = df.loc[:valid_idx, 'ColB'].fillna(0)

2. 向量化计算下方递推值

递推公式可转化为初始有效值 × 后续所有(1+colA)的累积乘积,利用cumprod实现批量计算:

# 构造(1+colA)序列,通过shift让当前行的colA对应下一行的ColB计算
growth = (1 + df['colA']).shift(-1)
# 从有效索引开始计算累积乘积,再乘以初始有效值
df.loc[valid_idx:, 'ColB'] = df.loc[valid_idx, 'ColB'] * growth.loc[valid_idx:].cumprod().fillna(1)

完整代码示例

import pandas as pd

# 构造原始DataFrame
data = {
    'date': ['1971-10-01', '1971-11-01', '1971-12-01', '1972-01-01', '1972-02-01',
             '1972-03-01', '1972-04-01', '1972-05-01', '1972-06-01'],
    'colA': [0.002451, 0.002445, 0.002439, 0.002433, 0.004854,
             0.000000, 0.002415, 0.002410, 0.002404],
    'ColB': [None, None, None, None, None, 250341816.0, None, None, None]
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])

# 处理ColB列
valid_idx = df['ColB'].first_valid_index()
df.loc[:valid_idx, 'ColB'] = df.loc[:valid_idx, 'ColB'].fillna(0)
growth = (1 + df['colA']).shift(-1)
df.loc[valid_idx:, 'ColB'] = df.loc[valid_idx, 'ColB'] * growth.loc[valid_idx:].cumprod().fillna(1)

# 打印结果(保留3位小数)
print(df.round(3))

关键说明

  • first_valid_index()直接定位ColB第一个非空值的位置,无需手动遍历;
  • fillna(0)批量替换上方空值,效率远高于循环;
  • cumprod()实现向量化累积乘积计算,避免逐行循环,大幅提升处理速度;
  • shift(-1)确保当前行的colA对应下一行的ColB计算逻辑,fillna(1)保证初始有效值位置的乘积为1,不影响结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:10:00