Pandas zählen (verschiedene) Äquivalente


288

Ich verwende Pandas als Datenbankersatz, da ich mehrere Datenbanken (Oracle, MSSQL usw.) habe und keine Befehlsfolge zu einem SQL-Äquivalent erstellen kann.

Ich habe eine Tabelle in einen DataFrame mit einigen Spalten geladen:

YEARMONTH, CLIENTCODE, SIZE, .... etc etc

In SQL würde die Anzahl der verschiedenen Clients pro Jahr gezählt:

SELECT count(distinct CLIENTCODE) FROM table GROUP BY YEARMONTH;

Und das Ergebnis wäre

201301    5000
201302    13245

Wie kann ich das bei Pandas machen?


Ich habe table.groupby (['YEARMONTH']) ['CLIENTCODE']. Unique () erstellt und kam mit zwei von YEARMONTH indizierten Serien und mit allen eindeutigen Werten. Wie zähle ich die Anzahl der Werte für jede Serie?
— Adriano Almeida

Für einige value_countskönnte die Antwort sein, die Sie suchen: pandas.pydata.org/pandas-docs/stable/generated/…
— sachinruk

Antworten:


434

Ich glaube, das ist was du willst:

table.groupby('YEARMONTH').CLIENTCODE.nunique()

Beispiel:

In [2]: table
Out[2]: 
   CLIENTCODE  YEARMONTH
0           1     201301
1           1     201301
2           2     201301
3           1     201302
4           2     201302
5           2     201302
6           3     201302

In [3]: table.groupby('YEARMONTH').CLIENTCODE.nunique()
Out[3]: 
YEARMONTH
201301       2
201302       3

2
Was ist, wenn ich mehrere Spalten habe, die zusammen eindeutig sein sollen, wie in .drop_duplicates (subset = ['col1', 'col2'])?
— ErnestScribbler

4
So greifen Sie auf diese eindeutige Anzahl zu. Da es keinen Spaltennamen gibt
— Tarun Khaneja

Vielen Dank, ich habe diesen Stil bei der Ausgabe von Resample verwendet. df_watch_record.resample ('M'). user.nunique () zählt die Anzahl der eindeutigen Benutzer, die sich pro Monat einen Film angesehen haben.
— Mehdi Kazemi

1
und sortiere sie mit table.groupby ('YEARMONTH'). CLIENTCODE.nunique (). sort_values ​​(aufsteigend = False)
— wllbll

Ist es möglich, die Gruppen-ID danach abzurufen nunique? Versuchen Sie, wie ich könnte, ich kann keinen Weg finden, da das Ergebnis dieser Antwort a ist Series, nicht a DataFrame.
— Josh Hansen

92

Hier ist eine andere Methode, die sehr einfach ist. Nehmen wir an, Ihr Datenrahmenname ist daatund der Spaltenname istYEARMONTH

daat.YEARMONTH.value_counts()

1
Ich mag diese Antwort. Wie kann ich diese Methode verwenden, wenn mein Spaltenname ein '.' drin (zB 'ck.Class')? Danke

5
daat ['ck.Class']. value_counts ()
— StatguyUser

28
Dies geht nicht auf die gestellte Frage ein.
— Aaron Schumacher

6
Dabei wird die Anzahl der Beobachtungen innerhalb jeder Gruppe gezählt, nicht der eindeutige Wert einer bestimmten Spalte, die jede Gruppe hat.
— Jason Goal

2
Dies ist die falsche Antwort. es spiegelt nicht die DISTINCTAnforderung aus der Frage wider ! Darüber hinaus enthält es keine Zählungen von NaN!
— Corey Levinson

47

Interessanterweise ist sehr oft len(unique())ein paar Mal (3x-15x) schneller als nunique().


11
Du meinst das? .CLIENTCODE.apply(lambda x: len(x.unique())), von hier
— user4015990

6
@ user32185 Sie müssten es in einen applyAnruf mit einem Lambda fallen lassen. Zum Beispiel df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0]).
— 3novak

3
Die Syntax ist nicht ganz klar, ich habe len(df['column'].unique())keine Lambda-Funktion benötigt
— mlh351

Ich habe TypeError: object of type 'method' has no len()von Chen'sKommentar bekommen, 3novak'sfür mich gearbeitet.
— Jason Goal

4

Bei Verwendung von crosstabwird mehr Informationen zurückgegeben alsgroupby nunique

pd.crosstab(df.YEARMONTH,df.CLIENTCODE)
Out[196]: 
CLIENTCODE  1  2  3
YEARMONTH          
201301      2  1  0
201302      1  2  1

Nach ein wenig Änderung erhalten Sie das Ergebnis

pd.crosstab(df.YEARMONTH,df.CLIENTCODE).ne(0).sum(1)
Out[197]: 
YEARMONTH
201301    2
201302    3
dtype: int64

Wie kann ich dies als zweispaltig exportieren YEARMONTHund count. Kann ich die Anzahl auch in absteigender Reihenfolge einstellen?
— Murtaza Haji

3

Ich benutze auch, nuniqueaber es wird sehr hilfreich sein, wenn Sie eine Aggregatfunktion wie 'min', 'max', 'count' or 'mean'etc. verwenden müssen.

df.groupby('YEARMONTH')['CLIENTCODE'].transform('nunique') #count(distinct)
df.groupby('YEARMONTH')['CLIENTCODE'].transform('min')     #min
df.groupby('YEARMONTH')['CLIENTCODE'].transform('max')     #max
df.groupby('YEARMONTH')['CLIENTCODE'].transform('mean')    #average
df.groupby('YEARMONTH')['CLIENTCODE'].transform('count')   #count

0

Mit der neuen Pandas-Version ist es einfach, als Datenrahmen zu erhalten

unique_count = pd.groupby(['YEARMONTH'], as_index=False).agg(uniq_CLIENTCODE =('CLIENTCODE',pd.Series.count))

0

Hier ein Ansatz, um die Anzahl über mehrere Spalten zu unterscheiden. Lassen Sie uns einige Daten haben:

data = {'CLIENT_CODE':[1,1,2,1,2,2,3],
        'YEAR_MONTH':[201301,201301,201301,201302,201302,201302,201302],
        'PRODUCT_CODE': [100,150,220,400,50,80,100]
       }
table = pd.DataFrame(data)
table

CLIENT_CODE YEAR_MONTH  PRODUCT_CODE
0   1       201301      100
1   1       201301      150
2   2       201301      220
3   1       201302      400
4   2       201302      50
5   2       201302      80
6   3       201302      100

Listen Sie nun die interessierenden Spalten auf und verwenden Sie groupby in einer leicht geänderten Syntax:

columns = ['YEAR_MONTH', 'PRODUCT_CODE']
table[columns].groupby(table['CLIENT_CODE']).nunique()

Wir erhalten:

YEAR_MONTH  PRODUCT_CODE CLIENT_CODE        
1           2            3
2           2            3
3           1            1

0

Unterscheidung der Spalte zusammen mit Aggregationen auf anderen Spalten

Um die eindeutige Anzahl von Werten für eine Spalte ( CLIENTCODEin Ihrem Fall) zu erhalten, können wir verwenden nunique. Wir können die Eingabe als Wörterbuch in aggFunktion übergeben, zusammen mit Aggregationen in anderen Spalten:

grp_df = df.groupby('YEARMONTH').agg({'CLIENTCODE': ['nunique'],
                                      'other_col_1': ['sum', 'count']})

# to flatten the multi-level columns
grp_df.columns = ["_".join(col).strip() for col in grp_df.columns.values]

# if you wish to reset the index
grp_df.reset_index(inplace=True)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.