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

为Pandas DataFrame补全缺失日期并填0:第一种方案失效原因?

补全缺失日期时reindex丢失数据的根本原因分析

场景描述

需要补全指定日期范围内的缺失日期并填充0,用于后续按日期统计绘图。参考某Stack Overflow方案时出现数据丢失,所有quantity值被清空为0,但另一方案可正常工作。

失效方案代码及输出

# (items_per_day is coming from DB)
date_now = datetime.now().date()
date_period = date_now-timedelta(weeks=1)

data = list(items_per_day)
print('data: ', data)

idx = pd.period_range(date_period, date_now)

df = pd.DataFrame(data)
print('df: ', df)

df.index = pd.DatetimeIndex(df.index)
print('df index: ', df)

df = df.reindex(idx, fill_value=0)
print('df: ', df)

输出:

data:  [{'date': datetime.date(2022, 8, 17), 'quantity': 1}, {'date': datetime.date(2022, 8, 18), 'quantity': 2}, {'date': datetime.date(2022, 8, 19), 'quantity': 3}]

df:           date  quantity
0  2022-08-17         1
1  2022-08-18         2
2  2022-08-19         3

df index:                                       date  quantity
1970-01-01 00:00:00.000000000  2022-08-17         1
1970-01-01 00:00:00.000000001  2022-08-18         2
1970-01-01 00:00:00.000000002  2022-08-19         3

df:             date  quantity
2022-08-13    0         0
2022-08-14    0         0
2022-08-15    0         0
2022-08-16    0         0
2022-08-17    0         0
2022-08-18    0         0
2022-08-19    0         0
2022-08-20    0         0

有效方案代码及输出

date_now = datetime.now().date()
date_period = date_now-timedelta(weeks=1)

data = list(items_per_day)
print('data: ', data)

idx = pd.period_range(date_period, date_now)

df = pd.DataFrame(data)
print('df: ', df)

df['date'] = pd.to_datetime(df['date'])

dates = pd.date_range(start=date_period, freq='D', periods=7)
df = df.set_index('date').reindex(dates.normalize().rename('date')).reset_index()
df['quantity'] = df['quantity'].fillna(0)
print('df: ', df)

输出:

data:  [{'date': datetime.date(2022, 8, 17), 'quantity': 1}, {'date': datetime.date(2022, 8, 18), 'quantity': 2}, {'date': datetime.date(2022, 8, 19), 'quantity': 3}]

df:           date  quantity
0  2022-08-17         1
1  2022-08-18         2
2  2022-08-19         3

df:     date  quantity
0 2022-08-13       0.0
1 2022-08-14       0.0
2 2022-08-15       0.0
3 2022-08-16       0.0
4 2022-08-17       1.0
5 2022-08-18       2.0
6 2022-08-19       3.0

失效根本原因

  1. 索引类型不匹配
    第一种方案中,idx = pd.period_range(date_period, date_now)生成的是PeriodIndex类型的日期索引,但你把原DataFrame的索引转成了DatetimeIndex(df.index = pd.DatetimeIndex(df.index)),两种索引类型完全不兼容,reindex时找不到任何匹配项,所以所有行都用fill_value=0填充。

  2. 索引未关联实际日期列
    更关键的是,第一种方案错误地把原DataFrame的默认整数索引转成了DatetimeIndex(变成了1970年的时间戳,因为整数0、1、2被转成了Unix起始时间的微秒级偏移),而没有把数据中的date列设置为索引。这就导致原数据的索引和你要补全的日期范围完全没有交集,reindex自然无法匹配到原有数据,全部被替换成0。

  3. 有效方案的核心差异
    有效方案正确地将date列转为Datetime类型后设置为索引,然后用同类型的DatetimeIndex(pd.date_range生成)进行reindex,此时索引值能和原有数据的日期匹配,缺失的日期才会填充NaN,最后再转成0,保留了原有数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 08:48:21