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

Pandas工作日时间索引下,0值列填充的非重索引解决方案求助

解决方案:保留日期索引的有效值填充

核心实现:用ffill()结合条件判断完成需求

你的需求本质是用最近的非零有效值填充0值,pandas原生的ffill()(前向填充)可以完美实现"取上一个有效值"的逻辑,全程不需要修改日期索引,一行代码就能搞定:

df['ColB'] = df['ColA'].mask(df['ColA'] == 0).ffill()

或者等价的where写法,逻辑完全一致:

df['ColB'] = df['ColA'].where(df['ColA'] != 0).ffill()

代码逻辑说明

  • mask(df['ColA'] == 0):将ColA中所有为0的位置替换为NaN
  • ffill():向前填充NaN值,自动取当前行之前最近的非NaN有效值(只按DataFrame的行顺序匹配,完全忽略日期间隔,正好对应你要的"上一个有效值",而非前一天的值)

用你的示例数据测试,代码如下:

import pandas as pd

# 构造示例DataFrame
data = {'ColA': [7, 3, 0, 5, 0]}
index = pd.to_datetime(['2019-11-11', '2019-11-12', '2019-11-13', '2019-11-14', '2019-11-15'])
df = pd.DataFrame(data, index=index)

# 生成ColB列
df['ColB'] = df['ColA'].mask(df['ColA'] == 0).ffill()
print(df)

输出结果完全符合预期:

ColA  ColB
2019-11-11     7   7.0
2019-11-12     3   3.0
2019-11-13     0   3.0
2019-11-14     5   5.0
2019-11-15     0   5.0

如果需要将ColB转为整数类型,可追加一步:

df['ColB'] = df['ColB'].astype(int)

你之前的方法出错原因

  1. 列表推导式+Timedelta:
    这种方法依赖日期的连续性,试图通过"日期减一天"取前值,但你的索引是工作日,周末/节假日不在索引内,自然会触发KeyError,逻辑本身就不符合需求。

  2. shift方法误用:
    df.loc[d,'ColA']取出的是单个标量值(如numpy.int64),而shift()是Series/DataFrame的方法,不能直接作用于标量,因此会报AttributeError。即使正确对Series使用shift(1),也只是取DataFrame的上一行,虽然逻辑接近需求,但你的写法完全错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:35:28