基于另一个系列或 PeriodIndex 的重采样或 groupby 聚合

Posted

技术标签:

【中文标题】基于另一个系列或 PeriodIndex 的重采样或 groupby 聚合【英文标题】:resampling or groupby aggregation based on another series or PeriodIndex 【发布时间】:2019-12-15 16:09:04 【问题描述】:

我有一个时间序列(通常为 15 分钟到 1 天)。我想在由 PeriodIndex 或基于 PeriodIndex 构建的另一个时间序列提供的更粗略的时期内聚合这个系列(总和、平均值)。

我在下面给出了一个例子——最后一行表达了我的意图但不起作用(resample 的论点不正确)。请注意,即使我的示例使用常规句点,这可以通过一些代码简单调用 resample() 来根据我的输入系列计算出基数/偏移量,但我不能指望在我的实际应用程序中使用这种规律性,我需要它来处理不规则但连续的周期索引。

ndx=pd.date_range(start="2005-01-01",freq="D",periods=40)
df0 = pd.DataFrame("data":np.arange(40),index=ndx)
periods = pd.period_range(start="2005-01-03",freq="W",periods=5)
df1 = df0.resample(periods).mean()  # Does not work

【问题讨论】:

df0.resample('W').mean() 有什么问题 见最后一句话。解决方案df0.resample('W').mean() 假定有一个规律的、已知的周期。我不能指望这个。 【参考方案1】:

查看 resample 的文档。 第一个参数是 rule - DateOffsetTimedeltastr - 数据的新频率。

您试图通过 PeriodRange,所以不要对 Pandas 感到惊讶 抱怨这种差异。

请注意,resample 只允许对“常规”周期进行分组。 还有一点需要注意的是 resample 会生成一个“连续序列” 重采样周期和任何不包含的此类周期 任何源行,都会创建一个 empty 组 (我想你不想要这个)。

看起来,您实际上想要执行分组之类的操作 按“不规则时期”排列并计算每个此类时期的平均值。

要做到这一点,请执行以下操作:

第 1 阶段:定义“边界日期”

per = pd.to_datetime(pd.Series([ '2005-01-01', '2005-01-04', '2005-01-09',
    '2005-01-16', '2005-02-01', '2005-02-14'], name='per'))

意思是:

第一期:[2005-01-01, 2005-01-03]。 第二个周期:[2005-01-04, 2005-01-08],以此类推。 最后一个周期:[2005-02-01, 2005-02-13]。

第 2 阶段:使用 from / to 日期创建一个 DataFrame

dfPer = pd.DataFrame('dFrom': per, 'dTo': per.shift(-1)\
    - pd.DateOffset(1)).dropna()

结果是:

       dFrom        dTo
0 2005-01-01 2005-01-03
1 2005-01-04 2005-01-08
2 2005-01-09 2005-01-15
3 2005-01-16 2005-01-31
4 2005-02-01 2005-02-13

第 3 阶段:计算结果并将其保存在 dfPer

meanVal 列中
dfPer['meanVal'] = dfPer.apply(
    lambda row: df0[row.dFrom:row.dTo].data.mean(), axis=1)

结果是:

       dFrom        dTo  meanVal
0 2005-01-01 2005-01-03      1.0
1 2005-01-04 2005-01-08      5.0
2 2005-01-09 2005-01-15     11.0
3 2005-01-16 2005-01-31     22.5
4 2005-02-01 2005-02-13     35.0

如你所见,我实际上并没有调用任何groupby,但是 df0[row.dFrom:row.dTo] 提供相同的功能。 它从 df0 中选择具有两个日期之间的索引值的行 (含)。

要检查有效性,如果您想将上述结果与 每个“组”中的源值,运行:

dfPer.apply(lambda row: df0[row.dFrom:row.dTo].data.values, axis=1)

【讨论】:

我对它不起作用并不感到惊讶。另请参阅对 WeNYoBen 的回复。我试图暗示,如果频率是规律的并且是已知的,我理解它的简单性。也许我需要用奇怪的句号重写它来强制解决这个问题? groupby 解决方案(您的第 2 步)暗示了我对这个问题的追求。如果您要使用我的示例设置来描述如何做到这一点,那可能是一个很好的答案。

以上是关于基于另一个系列或 PeriodIndex 的重采样或 groupby 聚合的主要内容,如果未能解决你的问题,请参考以下文章

每小时重新采样数据帧

从 Pandas 的重采样中获取索引

地图/采样时间序列数据到另一个时间系列db2

垃圾邮件分类的重采样数据集

基于另一个数据帧 Python 和 Pandas 从数据帧中采样

ArcGis重采样