给定一个多索引Pandas数据帧df2,我想计算每个类别中上一行的每一行的差异。
import pandas as pd
inner = ('a','b','c')
cols = ('A','B','C','D')
df1=pd.DataFrame(np.random.randn(3,4), index=inner, columns=cols)
df2=pd.concat([df1,df1],keys=['X','Y'])
DF2:
A B C D
X a -0.391804 -0.307916 -0.265643 -0.222193
b -0.142498 -1.389972 1.060328 1.207945
c 1.156881 1.596382 0.620923 0.592739
Y a -0.391804 -0.307916 -0.265643 -0.222193
b -0.142498 -1.389972 1.060328 1.207945
c 1.156881 1.596382 0.620923 0.592739
以下是我尝试的内容:
df2.groupby(level=[0]).apply(lambda x: df2.loc[x.index[:-1]-df2.loc[x.index[1:]]])
但是这将得到一个错误的结果数据框,其中有三个索引。
A B C D
X X a -0.391804 -0.307916 -0.265643 -0.222193
b -0.142498 -1.389972 1.060328 1.207945
Y Y a -0.391804 -0.307916 -0.265643 -0.222193
b -0.142498 -1.389972 1.060328 1.207945
答案 0 :(得分:3)
您不能按索引b / c的所有级别进行分组,然后每个组只有1行,并且没有任何内容可以减去。此外,使用非随机数据(减法不直观)让我们改变你的例子:
import pandas
import numpy as np
df = pandas.DataFrame(
data={'A': np.arange(8) ** 2, 'B': np.arange(8) ** 0.5},
index=pandas.MultiIndex.from_product([list('XY'), list('abcd')])
)
df
# A B
# X a 0 0.000000
# b 1 1.000000
# c 4 1.414214
# d 9 1.732051
# Y a 16 2.000000
# b 25 2.236068
# c 36 2.449490
# d 49 2.645751
因此,如果我们只对索引级别的子集进行分组,我们可以使用数据框的shift
方法在每个组中获得滚动差异:
df.groupby(level=[0]).transform(lambda g: g.shift(-1) - g)
# A B
# X a 1 1.000000
# b 3 0.414214
# c 5 0.317837
# d NaN NaN
# Y a 9 0.236068
# b 11 0.213422
# c 13 0.196262
# d NaN NaN