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