Python 如何减去数据帧组中的行?

Python 如何减去数据帧组中的行?,python,pandas,Python,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: 以下是我尝试过的: df2.groupby(level=[0]).ap

给定一个多索引数据帧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:

以下是我尝试过的:

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

您不能按索引b/c的所有级别进行分组,那么每个组将只有一行,并且没有任何可减去的内容。另外,使用非随机数据(减法不是直观的),让我们稍微改变一下您的示例:

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

您不能按索引b/c的所有级别进行分组,那么每个组将只有一行,并且没有任何可减去的内容。另外,使用非随机数据(减法不是直观的),让我们稍微改变一下您的示例:

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

如果您在索引的所有级别上发布了
groupby
,则每个组中只有一行,因此您所有
nan
的结果都是有意义的。如果您在索引的所有级别上发布了预期的输出,这将有助于理解您试图实现的目标。如果您在索引的所有级别上发布了
groupby
,则每个组中只有一行,因此,你所有的
NaNs
结果都是有意义的。如果你发布了预期的输出,这将有助于理解你想要完成什么