2017-05-17 8 views
-1

ich mit dem folgenden Pandas Datenrahmen arbeite (von CSV-Datei):Pandas Dataframe: Wie gruppiert man nach Wert?

---------------------------------------------- 
buyer_id  itemX itemY  bid1 bid2 
---------------------------------------------- 
buyer1   item1 item2  52 32 
buyer2   item1 item2  15 17 
.. .. 
buyer500  item1 item2  82 13 

Ich habe 500 Käufer für item1 bieten und item2, bieten die folgenden 200 Käufer für item3 und item4

buyer600  item3 item4  63 82 
.. 
.. 
buyer800  item3 item4  40 12 

I summiere Bid1 und bid2, damit ich nach maximalen Geboten suchen kann. Jetzt möchte ich die maximal 5 Gebote nur für jede Gruppe finden und behalten. group1 (item1 + item2) und group2 (item3 + item4). Wie kann ich es tun?

Hier ist mein Code so weit,

import pandas as pd 

df = pd.read)csv('myfile.csv') 
sum = (df[df.columns[4:]].sum(1)) 
df['sum'] = calc 
df.sort_values(['sort of sum'], ascending=[False], inplace=True) 
df.to_csv('results.csv') 

Ausgabe etwas wie

----------------------------------------- 
buyer itemX itemY sum of bid 
---------------------------------‌​-------- 
buyer13 item1 item2  350 
buyer2 item1 item2  283 
buyer65 item1 item2  236   
buyer602 item3 item4  80 
buyer703 item3 item4  76 
buyer640 item3 item4  69 

Antwort

1
#create a total column, sort by item name and total bid, then take the top 5 for each group. 
df.assign(total = df.bid1+df.bid2).sort_values(['itemX','total'],ascending=False).groupby('itemX').head(5) 
Out[2566]: 
    buyer_id itemX itemY bid1 bid2 total 
12 buyer61 item3 item4 44 60 104 
11 buyer51 item3 item4 52 32  84 
8 buyer21 item3 item4 15 55  70 
10 buyer41 item3 item4 40 17  57 
9 buyer31 item3 item4 52  3  55 
6 buyer500 item1 item2 82 13  95 
0  buyer1 item1 item2 52 32  84 
2  buyer3 item1 item2 52 32  84 
4  buyer5 item1 item2 52 32  84 
5  buyer6 item1 item2 15 60  75 
1

Eine Möglichkeit, diese beiden Datenrahmen, für die item1 & 2 Käufer zu erstellen wäre zu tun sein sollte, und ein anderes für das item3 & 4 Käufer

df1 = df[df['itemX'] == 'item1'] 
df2 = df[df['itemX'] == 'item3'] 

Dann können Sie eine neue Spalte erstellen, die die Gebote fasst

df1['sum_bids'] = df1['bid1'] + df1['bid2'] 

dann die Datenrahmen sort_values

sorted_df1 = df1.sort_values(['sum_bids'], ascending=False) 

mit sortieren Dann können Sie neu indizieren sie

sorted_df1.index = range(1,len(sorted_df1) + 1) 

Dann wählen Sie zuerst 5 Reihen

max_bids = sorted_df1[:5] 
1

Zuerst werde ich einen Beispieldatenrahmen erstellen, der meiner Meinung nach dem von Ihnen beschriebenen ähnlich ist.

bids_df = pd.DataFrame({'buyer_id': ['buyer' + str(i) for i in range(1, 501)] + ['buyer' + str(i) for i in range(600, 800)], 
        'itemX': ['item1'] * 500 + ['item3'] * 200, 
        'itemY': ['item2'] * 500 + ['item4'] * 200, 
        'bid1': [randint(10, 100) for _ in range(700)], 
        'bid2': [randint(10, 100) for _ in range(700)]}) 
bids_df = bids_df[['buyer_id', 'itemX', 'itemY', 'bid1', 'bid2']] 

Dann können wir eine Spalte für die Summe der Gebote hinzufügen und sortieren: Sie diese viel bereits in Ihrer Frage getan haben.

bids_df['bid_sum'] = bids_df['bid1'] + bids_df['bid2'] 
bids_df = bids_df.sort_values(by=['bid_sum'], ascending=False) 

Schließlich können wir die Gruppe Datenrahmen von Artikel, wie Sie beschreiben, und einfach die Top-5-Zeilen aus jeder Gruppe erhalten (da wir sie bereits durch Gebot Summe sortiert haben).

bids_df.groupby(lambda x: 'grp1' if bids_df.loc[x, 'itemX'] == 'item1' else 'grp2')\ 
    .head(5)\ 
    .sort_values(by=['itemX', 'bid_sum'], ascending=[True, False]) 

Dies ergibt die resultierende Datenrahmen:

 buyer_id itemX itemY bid1 bid2 bid_sum 
60 buyer61 item1 item2 99 97  196 
498 buyer499 item1 item2 98 97  195 
470 buyer471 item1 item2 92 99  191 
120 buyer121 item1 item2 98 93  191 
50 buyer51 item1 item2 100 91  191 
573 buyer673 item3 item4 100 94  194 
639 buyer739 item3 item4 90 95  185 
512 buyer612 item3 item4 89 94  183 
691 buyer791 item3 item4 100 78  178 
659 buyer759 item3 item4 87 91  178 
Verwandte Themen