2017-02-14 5 views
0

Ich habe einen Datenrahmen der folgenden Form:Pandas GROUPBY nur eine Spalte aggregieren

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

Nun, was ich möchte für jeden Verkäufer zu tun ist, den Anteil der Gesamtverkaufsmenge berechnet durch seinen größten Käufer aufgenommen. Ich habe einen Code, der das tut, aber ich muss den Index und die Gruppierung erneut zurücksetzen, was verschwenderisch ist. Es muss einen besseren Weg geben. Ich möchte eine Lösung, bei der ich jeweils eine Spalte zusammenfassen und die anderen gruppieren kann. Hier ist meine aktuellen Code:

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

ich ein wenig vereinfacht. In Wirklichkeit habe ich auch eine Zeitperiodenspalte, und deshalb möchte ich dies auf Verkäufer- und Zeitperiodenebene tun, deshalb gruppiere ich mich in gr3 nach dem Multiindex (in diesem Beispiel erscheint er als ein einzelner Index) . Ich dachte, dass es eine Lösung geben würde, bei der ich statt eines Reduzierens und Umgruppierens nur einen Index aus der Gruppe aggregieren könnte, was die anderen gruppiert, aber nicht in der Dokumentation oder online findet. Irgendwelche Ideen?

Antwort

0

Hier ist ein Einzeiler, aber es setzt einmal den Index auch:

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

Danke! Ich denke, die Frage ist, ob Groupby (Level = 0) schnell ist, da es der Index ist. Wenn ja, dann ist dies eine perfekte Antwort. – ErnestScribbler

+0

Ich habe Ihre ursprüngliche Lösung und meine zeitlich abgestimmt. Dein ist 30% schneller. Also, ich denke, meiner ist es nicht wert. – DyZ

+0

Ich habe es auch zeitlich gemessen. Ich denke, es ist nur die "Anwenden" -Linie, die es verlangsamt. – ErnestScribbler

0

ich dies mit pivot_table tun würde, und sendet dann (siehe What does the term "broadcasting" mean in Pandas documentation?).

Zunächst schwenkt die Daten mit seller_id im Index und buyer_id in den Säulen:

sales_pivot = sales.pivot_table(index='seller_id', columns='buyer_id', values='amount', aggfunc='sum') 

Dann gesagt, die Werte in jeder Reihe dividieren durch die Summe der Reihe:

result = sales_pivot.div(sales_pivot.sum(axis=1), axis=0) 

Schließlich Sie können result.max(axis=1) anrufen, um die Top-Aktie für jeden Verkäufer zu sehen.

+0

Danke! Dies würde jedoch eine Tabelle der Größe n_buyers * n_sellers erzeugen, die in diesem Spielzeugbeispiel funktionieren könnte, aber nie in den Speicher meines realen Datensatzes passen würde. – ErnestScribbler

Verwandte Themen