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

如何在不填充缺失时段的情况下重采样Pandas DataFrame?

如何在Pandas重采样稀疏时间序列时避免生成全NaN行?

你提到的问题确实很常见——当处理跨度大且稀疏的时间序列时,用resample会生成大量无意义的全NaN行,既浪费内存又拖慢计算。虽然dropna(how="all")能解决结果问题,但先创建再删除的方式不够高效,也不够严谨。

这里有个更优的方案:直接按目标时间粒度分组计算,而不是用resample生成所有时间点。

方法一:按日期分组(针对日粒度重采样)

对于你的示例,要计算日平均值,我们可以直接提取索引的日期部分作为分组键,再计算均值:

import numpy as np
import pandas as pd

# 构造你的示例数据
freq1 = pd.date_range("20000101", periods=10, freq="S")
freq2 = pd.date_range("20200101", periods=10, freq="S")
index = np.hstack([freq1.values, freq2.values])
data = np.random.randint(0, 100, (20, 10))
cols = list("ABCDEFGHIJ")
df = pd.DataFrame(index=index, data=data, columns=cols)

# 按日期分组计算日平均,直接得到有数据的日期结果
df_daily = df.groupby(df.index.date).mean()
# 如果需要将索引转回DatetimeIndex(默认是object类型的日期对象)
df_daily.index = pd.to_datetime(df_daily.index)

这个方法的核心是:groupby只会基于实际存在数据的日期创建分组,不会填充两个时间区间之间的空白日期,所以结果里只会有2000-01-01和2020-01-01两行,完全没有全NaN行。

方法二:灵活适配其他时间粒度(月度/季度等)

如果需要其他时间粒度的重采样,比如月度平均,可以用to_period()方法将索引转换为对应周期,再分组:

# 月度平均,仅保留有数据的月份
df_monthly = df.groupby(df.index.to_period('M')).mean()
# 可选:将周期索引转回时间戳(比如转为每月最后一天)
df_monthly.index = df_monthly.index.to_timestamp('M')

为什么这比resample+dropna更好?

  • 性能更优:resample会先生成从最早到最晚日期之间的所有时间点(你的示例里是7305天),哪怕这些时间点没有任何数据;而分组方法直接跳过空白区间,只处理有数据的时间粒度,内存占用和计算时间都会大幅降低。
  • 逻辑更严谨:不需要先创建无用数据再删除,从根源上避免了全NaN行的生成。

补充:如果一定要用resample怎么办?

如果因为某些场景必须用resample(比如需要统一的时间序列索引做后续对齐),可以在resample时结合closed、label等参数,但最终还是需要dropna。不过对于稀疏数据,还是优先推荐分组的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:07:46