将操作应用于熊猫中的分组

时间:2018-11-26 22:33:04

标签: python pandas grouping

编辑:我不是专门研究如何执行此特定操作,我需要这种行为来实现更复杂的功能。因此,出于问题的考虑,请假装该函数进行分组并返回对其执行了某些操作(但不求和)的数据帧。

所以说我有一个像这样的数据框:

import pandas as pd

df = pd.DataFrame({
    "page": [
        1, 1, 1,
        2, 2, 2,
        3, 3, 3, 3
    ],
    "x": [
            10, 12, 21, 
            0, 5, 7, 
            1, 10, 33, 40
    ]
})

我想计算每个x在其受尊重的页面内的差异。

我的设计方式如下:

def compute_diff(group):
    return group.assign(
        diff = [
            *(group.x.values[1:] - group.x.values[0:len(group.x)-1]),
            None
        ]
    )

df.groupby('page').apply(compute_diff)

现在这可以正常工作,但是问题是我得到了一个数据帧的数据帧,即:

        page    x   diff
page                
1   0   1   10  2.0
    1   1   12  9.0
    2   1   21  NaN
2   3   2   0   5.0
    4   2   5   2.0
    5   2   7   NaN
3   6   3   1   9.0
    7   3   10  23.0
    8   3   33  7.0
    9   3   40  NaN

请注意,我的索引有些混乱,我该如何清理它并获得更像这样的格式:

    page    x   diff                
0   1   10  2.0
1   1   12  9.0
2   1   21  NaN
3   2   0   5.0
4   2   5   2.0
5   2   7   NaN
6   3   1   9.0
7   3   10  23.0
8   3   33  7.0
9   3   40  NaN

我已经尝试使用unstack和reset_index进行一些操作,但是结果并不是我想要的,并且我在文档中没有发现任何东西。

2 个答案:

答案 0 :(得分:1)

如何改用GroupBy.diff

df.assign(diff=df.groupby('page').x.diff())

   page   x  diff
0     1  10   NaN
1     1  12   2.0
2     1  21   9.0
3     2   0   NaN
4     2   5   5.0
5     2   7   2.0
6     3   1   NaN
7     3  10   9.0
8     3  33  23.0
9     3  40   7.0

如果您坚持使用apply,请同时使用group_keys=False

df.groupby('page', as_index=False, group_keys=False).apply(compute_diff)

   page   x  diff
0     1  10   2.0
1     1  12   9.0
2     1  21   NaN
3     2   0   5.0
4     2   5   2.0
5     2   7   NaN
6     3   1   9.0
7     3  10  23.0
8     3  33   7.0
9     3  40   NaN

答案 1 :(得分:1)

.ilocdiff一起使用

df['diff']=df.groupby('page').x.apply(lambda x : -x.iloc[::-1].diff()).sort_index(level=0).values
df
Out[106]: 
   page   x  diff
0     1  10   2.0
1     1  12   9.0
2     1  21   NaN
3     2   0   5.0
4     2   5   2.0
5     2   7   NaN
6     3   1   9.0
7     3  10  23.0
8     3  33   7.0
9     3  40   NaN