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

Python中使用DataFrame.cumsum()时如何忽略首行shift(1)的NaN

解决DataFrame首行shift(1)产生NaN的问题

这问题我之前处理过,确实是shift(1)在首行因为没有上一行数据,必然返回NaN,结合你的水印跟踪需求,给你几个实用的解决方案:

方法一:用fillna()给NaN设置初始值

最直接的方式是给shift(1)后的结果填充一个符合业务逻辑的初始值(比如0,或者首行的cumsum值)。假设你的条件列是cond,代码示例如下:

import pandas as pd
import numpy as np

# 构造示例数据
df = pd.DataFrame({'tbid': [15, 25, 35, 45], 'cond': [False, True, False, True]})

# 先计算基础的cumsum
tbid_cumsum = df['tbid'].cumsum()

# 用np.where判断条件,同时给shift后的NaN填充初始值(这里用0,你可以根据业务调整)
df['Accum_tbid'] = np.where(
    df['cond'],
    tbid_cumsum,
    tbid_cumsum.shift(1).fillna(0)  # 首行NaN替换为0
)

如果你的业务逻辑要求首行即使不满足条件,也等于首行的cumsum值,只需要把fillna(0)改成fillna(tbid_cumsum.iloc[0])即可。

方法二:用向前填充(ffill)延续上一个有效水印值

如果你的场景中存在连续不满足条件的行,需要一直沿用最近一次满足条件的水印值,这种方式更合适:

tbid_cumsum = df['tbid'].cumsum()

# 先只在满足条件的行赋值cumsum,其余行设为NaN
df['Accum_tbid'] = np.where(df['cond'], tbid_cumsum, np.nan)

# 向前填充NaN,同时处理首行可能的NaN(用0或其他初始值)
df['Accum_tbid'] = df['Accum_tbid'].ffill().fillna(0)

这样连续不满足条件的行会自动继承上一次更新的水印值,首行的NaN也会被初始值覆盖。

方法三:自定义循环累加(适合小数据集)

如果你觉得向量化写法不够直观,也可以用循环逐行处理,逻辑完全贴合你的需求:

# 初始化累加值
current_accum = 0
accum_list = []

for _, row in df.iterrows():
    if row['cond']:
        # 满足条件时更新累加值
        current_accum += row['tbid']
    # 不管满足与否,都添加当前累加值到列表
    accum_list.append(current_accum)

df['Accum_tbid'] = accum_list

这个方法逻辑清晰,但要注意:iterrows的效率较低,只适合小数据集;如果是百万级别的数据,优先用前两种向量化方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:42:53