如何将Pandas DataFrame时间序列下采样至任意指定长度?
解决非标准时间比例的重采样(365个日值转272个均值)
这个问题我之前也碰到过,resample和asfreq确实只认标准时间单位,没法直接处理这种非整数倍的样本数转换。不过我们可以绕开时间单位的限制,直接从样本数量的比例入手,通过分组平均来实现你的需求。
具体实现思路
因为365个原始样本要转换成272个均值样本,每个新样本对应的原始样本数约为 365/272 ≈ 1.34 个。我们可以通过以下步骤完成:
- 生成新样本对应的原始数据分组边界
- 将原始数据按边界分组,计算每组的均值
- (可选)生成对应的新时间索引
代码示例(基于Pandas和Numpy)
假设你的数据是一个包含日值时间索引和VAL列的DataFrame:
import pandas as pd import numpy as np # 模拟你的365个日值数据(替换成你自己的真实数据) dates = pd.date_range(start='2023-01-01', periods=365) df = pd.DataFrame({'VAL': np.random.randn(365)}, index=dates)
步骤1:计算分组边界
我们用linspace生成272个分组的起始位置,确保覆盖所有365个原始样本:
# 生成272个分组的起始索引(从0到365,不包含终点) group_boundaries = np.linspace(0, 365, 272, endpoint=False) # 将原始样本的索引(0到364)分配到对应的分组中 df['group_id'] = np.digitize(np.arange(365), group_boundaries)
步骤2:计算每组的均值
按分组ID聚合,得到272个均值结果:
# 分组计算均值,得到272个值 resampled_vals = df.groupby('group_id')['VAL'].mean().values
步骤3:生成对应的新时间索引(可选)
如果你需要和原始时间范围对齐的新时间索引,可以按比例生成:
new_dates = pd.date_range(start=df.index[0], end=df.index[-1], periods=272) resampled_df = pd.DataFrame({'VAL': resampled_vals}, index=new_dates)
为什么这个方法可行?
因为你的原始数据是等间隔的日值序列,每个样本的时间间隔完全一致(1天),所以按样本数量比例分组,等价于按时间比例分组。每个新样本对应的原始数据区间的时间长度是均匀的,均值结果符合你的需求。
注意事项
- 如果你的原始数据存在缺失值,需要先补全缺失值(比如用
fillna),否则分组后的均值会不准确 - 如果你需要的不是简单均值,而是加权均值(比如靠近新样本点的原始值权重更高),可以考虑用滑动窗口加权或者插值后再采样,但你的需求是均值的话,上面的方法就足够了
内容的提问来源于stack exchange,提问作者Rasmus Svensson
相关产品推荐
相关产品推荐

