Jumlah panda (berbeda) setara

289

Saya menggunakan panda sebagai pengganti db karena saya memiliki banyak basis data (oracle, mssql, dll) dan saya tidak dapat membuat urutan perintah menjadi setara dengan SQL.

Saya memiliki tabel yang dimuat dalam DataFrame dengan beberapa kolom:

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

Dalam SQL, untuk menghitung jumlah klien yang berbeda per tahun adalah:

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

Dan hasilnya akan seperti itu

201301    5000
201302    13245

Bagaimana saya bisa melakukannya di panda?

Adriano Almeida
sumber
Saya telah melakukan table.groupby (['YEARMONTH']) ['CLIENTCODE']. Unique () dan datang dengan dua seri yang diindeks oleh YEARMONTH dan dengan semua nilai unik. Bagaimana cara menghitung jumlah nilai pada setiap seri?
Adriano Almeida
Untuk beberapa orang, value_countsmungkin jawaban yang Anda cari: pandas.pydata.org/pandas-docs/stable/generated/…
sachinruk

Jawaban:

434

Saya percaya ini yang Anda inginkan:

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

Contoh:

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
Dan Allan
sumber
2
Bagaimana jika saya memiliki beberapa kolom yang saya ingin menjadi unik bersama, seperti di .drop_duplicates (subset = ['col1', 'col2'])?
ErnestScribbler
4
Cara mengakses hitungan unik ini. Karena tidak ada nama kolom
Tarun Khaneja
Terima kasih banyak, saya menggunakan style ini pada output dari resample. df_watch_record.resample ('M'). user.nunique () menghitung jumlah pengguna unik yang telah menonton film per bulan.
Mehdi Kazemi
1
dan urutkan mereka dengan table.groupby ('YEARMONTH'). CLIENTCODE.nunique (). sort_values ​​(ascending = False)
wllbll
Apakah mungkin untuk mengambil pengenal grup setelah nunique? Cobalah sebisa mungkin saya tidak dapat menemukan jalan, karena hasil dari jawaban ini adalah Series, bukan a DataFrame.
Josh Hansen
93

Berikut adalah metode lain, lebih sederhana, katakanlah nama bingkai data Anda daatdan nama kolomnyaYEARMONTH

daat.YEARMONTH.value_counts()
Pengguna Statguy
sumber
1
Saya suka jawaban ini. Bagaimana saya bisa menggunakan metode ini jika nama kolom saya memiliki '.' di dalamnya (mis. 'ck.Class')? Terima kasih
5
daat ['ck.Class']. value_counts ()
StatguyUser
28
Ini tidak menjawab pertanyaan yang diajukan.
Aaron Schumacher
6
ini menghitung jumlah pengamatan dalam setiap kelompok, bukan nilai unik dari kolom tertentu yang dimiliki masing-masing kelompok.
Jason Goal
2
Ini adalah jawaban yang salah; itu tidak mencerminkan DISTINCTpersyaratan dari pertanyaan! Selain itu, itu tidak termasuk hitungan NaN!
Corey Levinson
47

Cukup menarik, sangat sering len(unique())beberapa kali (3x-15x) lebih cepat daripada nunique().

Roman Kh
sumber
11
Maksudmu ini? .CLIENTCODE.apply(lambda x: len(x.unique())), dari sini
user4015990
6
@ user32185 Anda harus memasukkannya ke dalam applypanggilan dengan lambda. Misalnya df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0]),.
3novak
3
Sintaksis tidak sepenuhnya jelas, saya menggunakan len(df['column'].unique())tidak perlu untuk fungsi lambda
mlh351
Saya dapatkan TypeError: object of type 'method' has no len()dari Chen'skomentar, 3novak'sbekerja untuk saya.
Jason Goal
4

Menggunakan crosstab, ini akan menghasilkan lebih banyak informasi daripadagroupby nunique

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

Setelah sedikit dimodifikasi, hasilkan hasilnya

pd.crosstab(df.YEARMONTH,df.CLIENTCODE).ne(0).sum(1)
Out[197]: 
YEARMONTH
201301    2
201302    3
dtype: int64
YOBEN_S
sumber
Bagaimana saya bisa mengekspor ini sebagai dua kolom YEARMONTHdan count. Dapatkah saya mengatur jumlah dalam urutan menurun?
Murtaza Haji
3

Saya juga menggunakan nuniquetetapi akan sangat membantu jika Anda harus menggunakan fungsi agregat seperti 'min', 'max', 'count' or 'mean'dll.

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
Gangaraju
sumber
0

Dengan versi panda baru, mudah diperoleh sebagai kerangka data

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

Di sini pendekatan untuk menghitung berbeda dari beberapa kolom. Mari kita punya beberapa data:

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

Sekarang, daftarkan kolom yang diminati dan gunakan grup dengan sintaks yang sedikit dimodifikasi:

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

Kami memperoleh:

YEAR_MONTH  PRODUCT_CODE CLIENT_CODE        
1           2            3
2           2            3
3           1            1
Ramon
sumber
0

Perbedaan kolom bersama dengan agregasi pada kolom lainnya

Untuk mendapatkan jumlah nilai yang berbeda untuk kolom apa pun ( CLIENTCODEdalam kasus Anda), kita dapat menggunakan nunique. Kami dapat meneruskan input sebagai aggfungsi kamus , bersama dengan agregasi pada kolom lain:

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)
Vivek Payasi
sumber