在数据透视期间选择不同的聚合功能

时间:2018-07-21 18:51:26

标签: python pandas dataframe pandas-groupby

数据帧:

df = pd.DataFrame({'First' : ['Mary', 'John', 'Jane', 'Mary', 'Jane', 'Mary', 'Mary'], 
                   'Last' : ['Johnson', 'Smith', 'Doe', 'Johnson', 'Doe', 'Johnson', 'Johnson'], 
                   'Group' : ['A', 'A', 'B', 'A', 'B', 'B', 'B'], 
                   'Measure' : [10, 2, 11, 1, 20, 15, 15]})

  First     Last Group  Measure
0  Mary  Johnson     A       10
1  John    Smith     A        2
2  Jane      Doe     B       11
3  Mary  Johnson     A        1
4  Jane      Doe     B       20
5  Mary  Johnson     B       15
6  Mary  Johnson     B       15

一个人可以出现在两个组中,这些数据中有期望和想要的重复项。

我想通过在列之间分布Group变量来重塑数据框。

我可以使用pivot_table()做到这一点:

df.pivot_table(index=['First','Last'],
               columns='Group',
               values='Measure',
               fill_value=0).reset_index()

Group First     Last    A     B
0      Jane      Doe  0.0  15.5
1      John    Smith  2.0   0.0
2      Mary  Johnson  5.5  15.0

默认情况下,将根据Measure对每个分组使用均值。我想基于来自原始Group变量的新生成的列指定聚合函数。在这种情况下,我想在A列上使用Max,在B列上使用sum。所需的输出:

  First     Last   A   B
0  Mary  Johnson  10  30
1  John    Smith   2   0
2  Jane      Doe   0  31

玛丽·约翰逊(Mary Johnson)的例子。对于她在A组中的值,max为10。对于她在B组中的值,sum为30。

尝试:

df.pivot_table(index=['First','Last'],
               columns='Group',
               values='Measure',
               fill_value=0,
               aggfunc = {'A': max,
                          'B': sum}).reset_index()

这导致错误消息KeyError: 'A'

在透视之后,如何旋转数据框并基于新列指定聚合函数?

2 个答案:

答案 0 :(得分:3)

您始终可以同时指定两者并仅过滤

ndf = df.pivot_table(index=['First','Last'],
               columns='Group',
               values='Measure',
               fill_value=0,
               aggfunc=['sum', 'max'])

ndf.loc[:, ((ndf.columns.get_level_values(0)=='max') & (ndf.columns.get_level_values(1)=='A') ) | \
           ((ndf.columns.get_level_values(0)=='sum') & (ndf.columns.get_level_values(1)=='B') )]

                  sum   max
        Group     B     A
First   Last        
Jane    Doe       31    0
John    Smith     0     2
Mary    Johnson   30    10

答案 1 :(得分:0)

您可以使用两个GroupBy对象,根据需要计算maxsum。然后将结果连接到一个单独的步骤。

A = df[df['Group'] == 'A'].groupby(['First', 'Last'])['Measure'].max().rename('A')
B = df[df['Group'] == 'B'].groupby(['First', 'Last'])['Measure'].sum().rename('B')

res = pd.concat([A, B], axis=1).fillna(0).astype(int).reset_index()

print(res)

  First     Last   A   B
0  Jane      Doe   0  31
1  John    Smith   2   0
2  Mary  Johnson  10  30