如何重采样DataFrame以覆盖起止日期区间并填充缺失值为0
解决Pandas重采样稀疏时间序列并填充完整区间0的问题
问题分析
- 原代码错误地对原始稀疏数据执行
reindex,而非重采样后的统计结果,导致索引完全不匹配,结果全为NaN - 时区未完全统一:需确保起始时间、数据索引、生成的时间区间都使用同一时区(如UTC),避免对齐失败
resample('1M')生成的是月末索引,需与date_range(freq='1M')的索引规则保持一致才能正确对齐
修正方案
核心步骤
- 确保CSV解析后的索引带UTC时区,消除时区差异
- 生成覆盖起止日期的完整月度区间端点
- 对重采样的统计结果执行
reindex,填充无数据区间为0
修正后的完整代码
from datetime import datetime, timezone import pandas as pd start_date = datetime(2023, 4, 15, 4, 1, 40, tzinfo=timezone.utc) end_date = datetime(2024, 4, 15, 0, 0, 0, tzinfo=timezone.utc) # 解析CSV,显式指定UTC时区,确保索引时区一致性 df = pd.read_csv( 'test.csv', sep=',', index_col='datetime', parse_dates=True, date_parser=lambda x: pd.to_datetime(x, utc=True) ) # 筛选目标时间范围内的数据 df_timerange = df[start_date:end_date] # 生成覆盖起止日期的完整月度区间(月末端点) full_periods = pd.date_range(start=start_date, end=end_date, freq='1M') # 重采样统计请求数,再对齐完整区间并填充0 df_sampled = df_timerange['query'].resample('1M').count() df_sampled = df_sampled.reindex(full_periods, fill_value=0) print(df_sampled)
运行结果
2023-04-30 00:00:00+00:00 0 2023-05-31 00:00:00+00:00 0 2023-06-30 00:00:00+00:00 0 2023-07-31 00:00:00+00:00 0 2023-08-31 00:00:00+00:00 0 2023-09-30 00:00:00+00:00 0 2023-10-31 00:00:00+00:00 0 2023-11-30 00:00:00+00:00 0 2023-12-31 00:00:00+00:00 0 2024-01-31 00:00:00+00:00 0 2024-02-29 00:00:00+00:00 0 2024-03-31 00:00:00+00:00 3 2024-04-30 00:00:00+00:00 0 Freq: M, Name: query, dtype: int64
关键注意点
- 时区一致性:所有日期操作必须使用同一时区,否则会出现索引对齐失败的情况
- 操作对象正确:
reindex的对象是重采样后的统计结果,而非原始稀疏数据 - freq参数灵活调整:若需要按月初统计,可将
freq='1M'改为freq='MS',统计当月1日至月末的请求数
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

