如何在MultiIndex DataFrame上实现非重叠滚动功能

Ped*_*raz 5 python python-3.x pandas

到目前为止,我已经找到了这个问题,但由于以下事实,它并没有解决我的问题:

  1. 我有一个MultiIndex DataFrame
  2. 内层有每个外层的不同数据量,因此我无法使用 len()

我有以下DataFrame

Outer Inner    Value        
  A     1     2.000000
  A     2     4.000000
  A     3     6.000000
  A     4     8.000000
  B     1     3.000000
  B     2     6.000000
  B     3     9.000000
  B     4     12.000000
  B     5     15.000000
Run Code Online (Sandbox Code Playgroud)

我想以outer非重叠的方式对每个值的最后两个值求和.因此,A我想要求和inner3 + 4,1 + 2.因为B我想求和inner4 + 5,2 + 3.注意,成对和应该从最后一个值开始.导致

Outer Inner    Value        
  A     2     6.000000
  A     4    14.000000
  B     3    15.000000
  B     5    27.000000
Run Code Online (Sandbox Code Playgroud)

tmt*_*prt 2

具有自定义重采样功能的 Groupby

您很可能需要自定义重采样才能执行此操作。这有点hacky但可能有用。

  1. 删除所有MulitIndexing 以仅处理常规groupby()
  2. groupby() 'Outer'以及.apply()每个组的自定义函数
  3. 自定义函数需要一组
    1. 确定群的偶数长度
    2. 向后选择该长度
    3. 将索引转换为秒
    4. 每两个样本对 DataFrame 重新采样一次resample(...).sum()
    5. Inner每两个对列重新采样一次以保留原始索引号resample(...).last()
    6. 将索引转换回 'Inner'
  4. 即使我们删除了MultiIndex, aMultiIndex仍然返回groupby(...).apply()

注意: 存在问题rolling,因为它滑动穿过值而不是单步穿过值(在非重叠方法中)。使用resample允许这样做。重新采样是基于时间的,索引需要以秒表示。

例子

import math
import pandas as pd

df = pd.DataFrame({
    'Outer': ['A','A','A','A','B','B','B','B','B'],
    'Inner': [1,2,3,4,1,2,3,4,5],
    'Value': [2.00,4.00,6.00,8.00,3.00,6.00,9.00,12.00,15.00]
})

def f(g):
    even_length = int(2.0 * math.floor(len(g) / 2.0))
    every_two_backwards = g.iloc[-even_length:]
    every_two_backwards.index = pd.TimedeltaIndex(every_two_backwards.index * 1000000000.0)
    resample_via_sum = every_two_backwards.resample('2s').sum().dropna()
    resample_via_sum['Inner'] = every_two_backwards.resample('2s').last()
    resample_via_sum = resample_via_sum.set_index('Inner')

    return resample_via_sum

resampled_df = df.groupby(['Outer']).apply(f)

print resampled_df
Run Code Online (Sandbox Code Playgroud)
             Value
Outer Inner       
A     2.0      6.0
      4.0     14.0
B     3.0     15.0
      5.0     27.0
Run Code Online (Sandbox Code Playgroud)