2017-02-14 5 views
0

У меня есть DataFrame следующего вида:панда GroupBy агрегирующей только один столбец

>>> 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

Вот один вкладыш, но он сбрасывает индекс один раз тоже:

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 
+0

Спасибо! Я думаю, вопрос в том, что groupby (level = 0) быстр, так как это индекс. Если да, то это прекрасный ответ. – ErnestScribbler

+0

Я приурочил свое оригинальное решение и мое. На 30% быстрее. Итак, я думаю, моя не достойна. – DyZ

+0

Я тоже приурочил его. Я думаю, что это только линия «применить», которая замедляет ее. – ErnestScribbler

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), чтобы увидеть верхнюю часть для каждого продавца.

+0

Спасибо! Но это создало бы таблицу размером n_buyers * n_sellers, которая могла бы работать в этом примере игрушек, но никогда не поместилась бы в памяти в моем реальном наборе данных. – ErnestScribbler

 Смежные вопросы

  • Нет связанных вопросов^_^