我有一个如下数据集:
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())
给出一个关于在期望布尔值时获取系列的错误。
答案 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)