2017-04-08 32 views
2

我在熊猫数据框中有数据,并且需要对它进行聚合。我需要在类似于下面的不同列上进行不同的聚合。如何使用pandas groupby实现多个聚合,引用特定列

group min(rank) min(rank) min sum 

title t_no  t_descr  rank stores 
A  1   a   1  1000 
B  1   a   1  1000 
B  2   b   2  800 
C  2   b   2  800 
D  1   a   1  1000 
D  2   b   2  800 
F  4   d   4  500 
E  3   c   3  700 

到:

title t_no  t_descr  rank stores 
A  1   a   1  1000 
B  1   a   1  1800 
C  2   b   2  800 
D  1   a   1  1800 
E  3   c   3  700 
F  4   d   4  500 

你会发现,标题B和d已经汇总,保持T_NR中& t_descr是对应的最低军衔为各自的题目组,而商店总结。 t_no & t_descr只是任意文本。我需要按冠军头衔排名,总结商店,并保留相应的t_no & t_descr。

我该如何在一个熊猫群体中做到这一点?这是虚拟数据;我正在处理的真正问题有更多的聚合,我不想单独做每个聚合,我知道该怎么做。

我从下面开始,但是意识到我真的需要t_no & t_descr的最大值是基于子组的排列,而不是列本身。

aggs = { 
'rank': 'min', 
't_no': 'min', # need t_no for row that is min(rank) by title. 
't_descr': 'min' # need t_descr for row that is min(rank) by title. 
} 

df2.groupby('title').agg(aggs).reset_index() 

也许有办法用lambda来做到这一点?我确信有一个简单的方法来做到这一点。如果groupby不是正确的方法,我显然会接受建议。

谢谢!

+0

加入它,我发布了一个答案是与你的尝试类似,但后来意识到你正在尝试做一些不同的事情。如果您更改了“t_descr”的字母顺序以显示该列基于另一列的最小值而不是自己的最小值的示例,将会有所帮助。 – pshep123

+0

嘿@ pshep123感谢您的评论!我更新了一下这个例子。为了解释,t_no和t_descr只是随机文本字段。我需要按照标题保留与排名最小值相关的字段。 – claybot

+0

更改B或D中的“t_descr”以颠倒字母顺序,您的示例将突出显示该需求。当前代码中找到't_descr'的最小值,尽管使用了不正确的逻辑,但仍会产生所需的结果。 – pshep123

回答

1

两个步骤...
总门店之和为idxmin ... rank
然后使用idxmin切片原始数据框,并与总

agged = df.groupby('title').agg(dict(rank='idxmin', stores='sum')) 
df.loc[agged['rank'], ['title', 't_no', 't_descr', 'rank']].join(agged.stores, on='title') 

    title t_no t_descr rank stores 
0  A  1  a  1 1000 
1  B  1  a  1 1800 
3  C  2  b  2  800 
4  D  1  a  1 1800 
7  E  3  c  3  700 
6  F  4  d  4  500 
+0

谢谢!这正是我需要的。真的很感谢帮助。 – claybot

0

这是@piRSquared稍微不同的方法,但可以让你在同一个地方:

代码:

# Set min and sum functions according to columns and generate new dataframe 
f = {'rank':min, 'rank':min, 'stores':sum} 
grouped = df.groupby('title').agg(f).reset_index() 

# Then merge with original dataframe (keeping only the merged and new columns) 
pd.merge(grouped, df[['title','rank','t_no','t_descr']], on=['title','rank']) 

输出:

title stores rank t_no t_descr 
0  A 1000  1  1  a 
1  B 1800  1  1  a 
2  C  800  2  2  b 
3  D 1800  1  1  a 
4  E  700  3  3  c 
5  F  500  4  4  d 

当然您可以按照您认为合适的方式组织这些列。

+0

真的很感谢帮助,但这个解决方案对我不起作用 - @ piRsquared的答案就是我需要的。谢谢! – claybot

相关问题