我有一个以下形式的DataFrame:
>>> sales = pd.DataFrame({'seller_id':list('AAAABBBB'),'buyer_id':list('CCDECDEF'),\
'amount':np.random.randint(10,20,size=(8,))})
>>> sales = sales[['seller_id','buyer_id','amount']]
>>> sales
seller_id buyer_id amount
0 A C 18
1 A C 15
2 A D 11
3 A E 12
4 B C 16
5 B D 18
6 B E 16
7 B F 19
现在我想做的是每个卖家计算其最大买家占用的总销售额的份额。我有代码执行此操作,但我必须继续重置索引并再次分组,这是浪费。一定有更好的方法。我想要一个解决方案,我可以一次聚合一列,并保持其他列分组。 这是我目前的代码:
>>> gr2 = sales.groupby(['buyer_id','seller_id'])
>>> seller_buyer_level = gr2['amount'].sum() # sum over different purchases
>>> seller_buyer_level_reset = seller_buyer_level.reset_index('buyer_id')
>>> gr3 = seller_buyer_level_reset.groupby(seller_buyer_level_reset.index)
>>> result = gr3['amount'].max() / gr3['amount'].sum()
>>> result
seller_id
A 0.589286
B 0.275362
我简化了一下。实际上我也有一个时间段列,因此我想在卖家和时间段级别执行此操作,这就是为什么在gr3中我按多索引进行分组(在此示例中,它显示为单个索引) 。 我认为会有一个解决方案,而不是减少和重新组合,我只能聚合一个索引,而其他索引分组,但无法在文档或在线中找到它。有什么想法吗?
答案 0 :(得分:0)
这里是一个单行,但它也会重置索引一次:
sales.groupby(['seller_id','buyer_id']).sum().\
reset_index(level=1).groupby(level=0).\
apply(lambda x: x.amount.max()/x.amount.sum())
#seller_id
#A 0.509091
#B 0.316667
#dtype: float64
答案 1 :(得分:0)
我会使用pivot_table
然后广播(请参阅What does the term "broadcasting" mean in Pandas documentation?)。
首先,使用索引中的seller_id
和列中的buyer_id
来转移数据:
sales_pivot = sales.pivot_table(index='seller_id', columns='buyer_id', values='amount', aggfunc='sum')
然后,将每行中的值除以所述行的总和:
result = sales_pivot.div(sales_pivot.sum(axis=1), axis=0)
最后,您可以致电result.max(axis=1)
查看每个卖家的最高分享。