Pandas DataFrame MultiIndex groupby滚动操作,缺少日期

时间:2017-02-09 05:56:37

标签: python pandas

我有一个具有MultiIndex的数据框,其中索引的最后一列是日期。我试图在具有特定频率的列上进行滚动操作。据我了解,如果我有一个TimeIndex,通常的pandas方法是用频率字符串调用滚动函数(例如,如果我希望窗口为两天,则为“2D”)。建议的另一种方法是重新采样TimeIndex,然后应用整数2的滚动函数。基本上我想要做的是按除最后一列之外的所有列进行分组,然后告诉滚动列使用最后一列timedelta特定的滚动。下面是一个演示这个的例子:

from datetime import datetime
import pandas as pd
multi_index = pd.MultiIndex.from_tuples([
    ("A", datetime(2017, 1, 1)), 
    ("A", datetime(2017, 1, 2)), 
    ("A", datetime(2017, 1, 3)), 
    ("A", datetime(2017, 1, 4)),
    ("B", datetime(2017, 1, 1)),
    ("B", datetime(2017, 1, 3)),
    ("B", datetime(2017, 1, 4))])
df = pd.DataFrame(index=multi_index, data={"colA": [1, 1, 1, 1, 1, 1, 1]})
display(df)
df.groupby([df.index.get_level_values(0), pd.Grouper(freq="1D", level=-1)]).sum().rolling(2).sum

以上代码不会为(B,datetime(2017,1,2))创建一行,因此滚动总和将全部为两行。

一种丑陋的方式可以解决这个问题,只有当一个团队有所有日子的时候才会在滚动之前解开堆积,填充和堆叠:

df.groupby([df.index.get_level_values(0), pd.Grouper(freq="1D", level=-1)]
).sum().unstack().fillna(0).stack().rolling(2).sum()

毋庸置疑,这是一个丑陋的黑客,缓慢且容易出错。有没有一种很好的方法可以实现我需要的东西而无需大量操作?理想情况下,某种方式告诉石斑鱼采取时间戳列或填充缺失值本身?

1 个答案:

答案 0 :(得分:2)

您可以使用groupby + resample + fillna - 需要版本pandas 0.19.0

multi_index = pd.MultiIndex.from_tuples([
    ("A", datetime(2017, 1, 1)), 
    ("A", datetime(2017, 1, 2)), 
    ("A", datetime(2017, 1, 3)), 
    ("A", datetime(2017, 1, 4)),
    ("B", datetime(2017, 1, 1)),
    ("B", datetime(2017, 1, 3)),
    ("B", datetime(2017, 1, 4))])
df = pd.DataFrame(index=multi_index, data={"colA": [1, 2, 3, 4, 1, 2, 3]})
print (df)
              colA
A 2017-01-01     1
  2017-01-02     2
  2017-01-03     3
  2017-01-04     4
B 2017-01-01     1
  2017-01-03     2
  2017-01-04     3

b = df.groupby(level=0).resample('1D', level=1).sum().fillna(0).rolling(2).sum()
print (b)
              colA
A 2017-01-01   NaN
  2017-01-02   3.0
  2017-01-03   5.0
  2017-01-04   7.0
B 2017-01-01   5.0
  2017-01-02   1.0
  2017-01-03   2.0
  2017-01-04   5.0