使用多个参数应用聚合

时间:2016-01-26 02:39:28

标签: python pandas

我有一个如下数据集:

df = pd.DataFrame({
                       "person":[i for i in range(5)]*2, 
                       "val_1":np.random.randn(10),
                       "val_1_entry": ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 
                       "val_2":np.random.randn(10),
                       "val_2_entry": ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
                      }).sort_values('person')

   person     val_1 val_1_entry     val_2 val_2_entry
0       0 -0.174681           a  0.464660           b
5       0  0.049361           f  1.332204           g
1       1  1.113805           b  0.261678           c
6       1 -0.847422           g -0.272731           h
2       2 -0.583784           c  1.815190           d
7       2 -1.101540           h -1.660562           i
3       3  0.919850           d  0.651178           e
8       3  1.309287           i  0.776856           j
4       4  1.395888           e  0.180980           f
9       4  0.699365           j -1.108057           k

对于每个人,我想聚合数据,取最小值和最大值(可能还有一些任意值),然后取相应的值。如果我做一个简单的聚合,我采用最小值和最大值,这很好......

df_proc = (df
           .groupby('person')
           .agg({'val_1': ['max', 'min'],
                 'val_2': ['max', 'min']}))

           val_1               val_2          
             max       min       max       min
person                                        
0       0.049361 -0.174681  1.332204  0.464660
1       1.113805 -0.847422  0.261678 -0.272731
2      -0.583784 -1.101540  1.815190 -1.660562
3       1.309287  0.919850  0.776856  0.651178
4       1.395888  0.699365  0.180980 -1.108057

但我喜欢的是与自己的变量在同一行中的相应条目。

           val_1               val_2           val_1_entry val_2_entry
             max       min       max       min         max         min
person                                        
0       0.049361 -0.174681  1.332204  0.464660           f           a
1       1.113805 -0.847422  0.261678 -0.272731           b           g
2      -0.583784 -1.101540  1.815190 -1.660562           c           h
3       1.309287  0.919850  0.776856  0.651178           i           d
4       1.395888  0.699365  0.180980 -1.108057           e           j

等等。

如果我可以使用lambda,我会在一个字段中返回与另一个元素的索引相对应的值,但是我很难看到如何在多个列上使用聚合。

另一种方法可能是对数据应用过滤器,对于每个组,选择具有max和min的行然后分散数据,但我不太确定如何做到这一点; query不能使用分组对象,而过滤器会给我一个df.groupby('person').filter(lambda x: x['val_1'] == x['val_1']min())给出一个关于在期望布尔值时获取系列的错误。

1 个答案:

答案 0 :(得分:1)

您可以使用群组上的apply()来实现此目的。假设df定义如上,这将吐出所述的所需输出:

val_cols = ['val_1', 'val_2']
def minmax(data):
    mins, maxs = [], []
    for vc in val_cols:
        data= data.sort(vc)  # use sort_values() with newer Pandas version
        mins.append(pd.Series(data.iloc[0][[vc, '%s_entry' % vc]], name='min')) 
        maxs.append(pd.Series(data.iloc[-1][[vc, '%s_entry' % vc]], name='max'))
    min = pd.concat(mins)
    max = pd.concat(maxs)
    return pd.DataFrame([min, max])
df.groupby('person').apply(minmax).unstack(-1)