Pandy liczą (wyraźne) odpowiedniki


289

Używam pand jako zamiennika bazy danych, ponieważ mam wiele baz danych (Oracle, mssql itp.) I nie jestem w stanie wykonać sekwencji poleceń do odpowiednika SQL.

Mam tabelę załadowaną do DataFrame z niektórymi kolumnami:

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

W SQL, policzenie liczby różnych klientów rocznie byłoby:

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

I wynik byłby

201301    5000
201302    13245

Jak mogę to zrobić w pandach?


Zrobiłem table.groupby (['YEARMONTH']) ['CLIENTCODE']. Unique () i przyszedłem z dwiema seriami indeksowanymi przez YEARMONTH i ze wszystkimi unikalnymi wartościami. Jak policzyć liczbę wartości w każdej serii?
Adriano Almeida

Dla niektórych value_countsmoże być odpowiedzią, której szukasz: pandas.pydata.org/pandas-docs/stable/generated/…
sachinruk

Odpowiedzi:


434

Wierzę, że tego właśnie chcesz:

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

Przykład:

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
Co jeśli mam wiele kolumn, które chcę być unikalne razem, jak w .drop_duplicates (podzbiór = ['col1', 'col2'])?
ErnestScribbler

4
Jak uzyskać dostęp do tej unikalnej liczby. Ponieważ nie ma nazwy kolumny
Tarun Khaneja

Wielkie dzięki, użyłem tego stylu na wyjściu ponownego próbkowania. df_watch_record.resample ('M'). user.nunique () zlicza liczbę unikalnych użytkowników, którzy oglądali film miesięcznie.
Mehdi Kazemi

1
i posortuj je za pomocą table.groupby ('YEARMONTH'). CLIENTCODE.nunique (). sort_values ​​(ascending = False)
wllbll,

Czy można później pobrać identyfikator grupy nunique? Spróbuj, jak mogę, nie mogę znaleźć sposobu, ponieważ wynikiem tej odpowiedzi jest, a Seriesnie DataFrame.
Josh Hansen

93

Oto inna metoda, bardzo prosta, powiedzmy, że twoja nazwa ma nazwę daati nazwa kolumny toYEARMONTH

daat.YEARMONTH.value_counts()

1
Podoba mi się ta odpowiedź. Jak mogę użyć tej metody, jeśli nazwa mojej kolumny ma „.” w nim (np. „ck.Class”)? Dzięki

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

28
To nie dotyczy zadanego pytania.
Aaron Schumacher

6
zliczając liczbę obserwacji w każdej grupie, a nie unikalną wartość określonej kolumny w każdej grupie.
Jason Gol

2
To jest nieprawidłowa odpowiedź; nie odzwierciedla DISTINCTwymagań zawartych w pytaniu! Co więcej, nie obejmuje liczby NaN!
Corey Levinson

47

Co ciekawe, bardzo często len(unique())jest kilka razy (3x-15x) szybszy niż nunique().


11
Masz na myśli to? .CLIENTCODE.apply(lambda x: len(x.unique())), stąd
user4015990

6
@ user32185 musisz upuścić go w applyrozmowie z lambda. Na przykład df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0]).
3novak

3
Składnia nie jest całkowicie jasna, nie użyłem len(df['column'].unique())funkcji lambda
mlh351 24.09.18

Dostałem TypeError: object of type 'method' has no len()od Chen'skomentarza, 3novak'spracował dla mnie.
Jason Gol

4

Przy użyciu crosstabzwróci to więcej informacji niżgroupby nunique

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

Po niewielkiej modyfikacji zmodyfikuj wynik

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

Jak mogę to wyeksportować jako dwie kolumny YEARMONTHi count. Czy mogę również ustawić liczbę w kolejności malejącej?
Murtaza Haji

3

Ja również używam, nuniqueale będzie bardzo pomocne, jeśli musisz użyć funkcji agregującej, takiej jak 'min', 'max', 'count' or 'mean'itp.

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

Dzięki nowej wersji pand łatwo jest uzyskać ramkę danych

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

0

W tym przypadku podejście ma mieć odrębną liczbę w wielu kolumnach. Chodźmy trochę danych:

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

Teraz wypisz interesujące kolumny i użyj groupby w nieco zmodyfikowanej składni:

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

Otrzymujemy:

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

0

Wyróżnia kolumnę wraz z agregacjami na innych kolumnach

Aby uzyskać odrębną liczbę wartości dla dowolnej kolumny ( CLIENTCODEw twoim przypadku), możemy użyć nunique. Możemy przekazać dane wejściowe jako słownik aggfunkcji wraz z agregacjami w innych kolumnach:

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.