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

时间:2015-09-28 22:10:30

标签: 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'])

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

1 个答案:

答案 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