Datenrahmen gruppieren und Summe UND Anzahl erhalten?

79

Ich habe einen Datenrahmen, der so aussieht:

              Company Name              Organisation Name  Amount
10118  Vifor Pharma UK Ltd  Welsh Assoc for Gastro & Endo 2700.00
10119  Vifor Pharma UK Ltd    Welsh IBD Specialist Group,  169.00
10120  Vifor Pharma UK Ltd             West Midlands AHSN 1200.00
10121  Vifor Pharma UK Ltd           Whittington Hospital   63.00
10122  Vifor Pharma UK Ltd                 Ysbyty Gwynedd   75.93

Wie summiere Amountund zähle ich die Organisation Name, um einen neuen Datenrahmen zu erhalten, der so aussieht?

              Company Name             Organisation Count   Amount
10118  Vifor Pharma UK Ltd                              5 11000.00

Ich weiß, wie man summiert oder zählt:

df.groupby('Company Name').sum()
df.groupby('Company Name').count()

Aber nicht wie man beides macht!

Richard
quelle

Antworten:

143

Versuche dies:

In [110]: (df.groupby('Company Name')
   .....:    .agg({'Organisation Name':'count', 'Amount': 'sum'})
   .....:    .reset_index()
   .....:    .rename(columns={'Organisation Name':'Organisation Count'})
   .....: )
Out[110]:
          Company Name   Amount  Organisation Count
0  Vifor Pharma UK Ltd  4207.93                   5

oder wenn Sie den Index nicht zurücksetzen möchten:

df.groupby('Company Name')['Amount'].agg(['sum','count'])

oder

df.groupby('Company Name').agg({'Amount': ['sum','count']})

Demo:

In [98]: df.groupby('Company Name')['Amount'].agg(['sum','count'])
Out[98]:
                         sum  count
Company Name
Vifor Pharma UK Ltd  4207.93      5

In [99]: df.groupby('Company Name').agg({'Amount': ['sum','count']})
Out[99]:
                      Amount
                         sum count
Company Name
Vifor Pharma UK Ltd  4207.93     5
MaxU
quelle
2
@MaxU gibt es eine Möglichkeit, Summe und Zählung auf verschiedene, aber mehrere Coulmns anzuwenden. Wenn ich versuche, die Spalten als Liste wie folgt anzugeben: agg ({['hotel_name', 'hotel_country']: 'count', ['cost', 'Revenue', 'clicks']: 'sum'}) gibt es "TypeError: unhashable type: 'list'" error
CanCeylan
@CanCeylan weiß nicht, ob es möglich ist, dies in einer Groupby-Klausel zu tun, aber Sie können dies erreichen, indem Sie dem Datenrahmen zuvor eine Dummy-Zählspalte hinzufügen und dann eine Groupby-Summe erstellen:df['count'] = 1
Karl Anka
1
Schließlich 2 Stunden Suche, wie dies zu tun ist ... nur die 3. Option: df.groupby ('Firmenname'). Agg ({'Betrag': ['Summe', 'Anzahl']}) hat für mich funktioniert .
Charo
Hallo, danke für diese großartige Lösung. In meinem speziellen Fall verwende ich Ihre Lösung für zwei verschiedene Spalten, um die Summe zu erhalten und die Anzahl der Zeilen zu zählen. Leider bekomme ich die Anzahl der Zeilen zweimal (ofc., Weil es für beide Spalten zählt). Gibt es eine Möglichkeit, eine der .counts zu entfernen, damit meine Tabelle sauber aussieht? df.groupby(df['L2 Name'])[["Amount arrear","VSU"]].agg(['sum','count'])
MLAlex
17

Nur für den Fall, dass Sie sich gefragt haben, wie Spalten während der Aggregation umbenannt werden sollen, erfahren Sie hier, wie

pandas> = 0,25: Benannte Aggregation

df.groupby('Company Name')['Amount'].agg(MySum='sum', MyCount='count')

Oder,

df.groupby('Company Name').agg(MySum=('Amount', 'sum'), MyCount=('Amount', 'count'))

                       MySum  MyCount
Company Name                       
Vifor Pharma UK Ltd  4207.93        5
cs95
quelle
Dies sollte die ausgenommene Antwort sein. Gibt es eine Möglichkeit, alte Fragen / Antworten mit der neuen besseren Methode zu aktualisieren? Die ausgenommene Antwort ist nicht falsch, nur nicht mehr der beste Weg.
JSharm
@JSharm Natürlich können Sie die Meinung des OP nicht ändern, aber Sie können die Beiträge, die Sie für verdient halten, ganz oben zu bewerten. Wenn genug Leute so denken und handeln, wie Sie es tun, werden wir eines Tages dort sein;) PS, um die akzeptierte Antwort nicht zu beschatten, denke ich immer noch, dass es die beste Antwort auf diese Frage ist, solange Pandas weiterhin die Syntax unterstützen. Ich bin mir ziemlich sicher, dass es noch eine Weile dauern wird.
cs95
3

Wenn Sie viele Spalten haben und nur eine anders ist, können Sie Folgendes tun:

In[1]: grouper = df.groupby('Company Name')
In[2]: res = grouper.count()
In[3]: res['Amount'] = grouper.Amount.sum()
In[4]: res
Out[4]:
                      Organisation Name   Amount
Company Name                                   
Vifor Pharma UK Ltd                  5  4207.93

Beachten Sie, dass Sie die Spalte Organisationsname nach Belieben umbenennen können.

JSharm
quelle
1
df.groupby('Company Name').agg({'Organisation name':'count','Amount':'sum'})\
    .apply(lambda x: x.sort_values(['count','sum'], ascending=False))
cvsnow
quelle