如何减去数据帧组内的行?

Rex*_*Rex 1 python pandas

给定一个多索引 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'])
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

df2.groupby(level=[0]).apply(lambda x: df2.loc[x.index[:-1]-df2.loc[x.index[1:]]])
Run Code Online (Sandbox Code Playgroud)

但这会得到一个带有三级索引的错误结果数据框。

             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
Run Code Online (Sandbox Code Playgroud)

Pau*_*l H 5

您不能按索引 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
Run Code Online (Sandbox Code Playgroud)

所以如果我们只沿着索引级别的一个子集分组,我们可以使用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
Run Code Online (Sandbox Code Playgroud)