นับแพนด้า (แตกต่างกัน) เทียบเท่า


289

ฉันใช้แพนด้าเป็นตัวแทนที่ฐานข้อมูลเนื่องจากมีหลายฐานข้อมูล (oracle, mssql และอื่น ๆ ) และฉันไม่สามารถสร้างลำดับของคำสั่งให้เทียบเท่ากับ SQL ได้

ฉันมีตารางที่โหลดใน DataFrame ด้วยบางคอลัมน์:

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

ใน SQL เพื่อนับจำนวนลูกค้าที่แตกต่างกันต่อปีจะเป็น:

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

และผลก็จะเป็น

201301    5000
201302    13245

ฉันจะทำเช่นนั้นในหมีแพนด้าได้อย่างไร


ฉันได้ทำ table.groupby (['YEARMONTH']) ['CLIENTCODE']. unique () และมาพร้อมกับซีรีส์สองชุดที่จัดทำดัชนีโดย YEARMONTH และด้วยค่าที่ไม่ซ้ำกันทั้งหมด วิธีการนับจำนวนของค่าในแต่ละซีรี่ส์?
Adriano Almeida

สำหรับบางคนvalue_countsอาจเป็นคำตอบที่คุณต้องการ: pandas.pydata.org/pandas-docs/stable/generated/…
sachinruk

คำตอบ:


434

ฉันเชื่อว่านี่คือสิ่งที่คุณต้องการ:

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

ตัวอย่าง:

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
จะเกิดอะไรขึ้นถ้าฉันมีหลายคอลัมน์ที่ฉันต้องการให้ไม่ซ้ำกันเช่นใน. drop_duplicates (subset = ['col1', 'col2'])
ErnestScribbler

4
วิธีเข้าถึงการนับที่ไม่ซ้ำกันนี้ เนื่องจากไม่มีชื่อคอลัมน์
Tarun Khaneja

ขอบคุณมากฉันใช้สไตล์นี้กับผลลัพธ์ตัวอย่าง df_watch_record.resample ('M'). user.nunique () นับจำนวนผู้ใช้ที่ไม่ซ้ำที่ดูภาพยนตร์ต่อเดือน
Mehdi Kazemi

1
และจัดเรียงด้วย table.groupby ('YEARMONTH') CLIENTCODE.nunique (). sort_values ​​(จากน้อยไปมาก = เป็นเท็จ)
wllbll

มันเป็นไปได้ที่จะดึงตัวระบุกลุ่มหลังnunique? ลองเป็นฉันฉันอาจจะไม่สามารถหาวิธีเนื่องจากผลของคำตอบนี้เป็นไม่ได้Series DataFrame
Josh Hansen

93

นี่คือวิธีอื่นง่ายมากสมมติว่าชื่อ dataframe ของคุณdaatและชื่อคอลัมน์คือYEARMONTH

daat.YEARMONTH.value_counts()

1
ฉันชอบคำตอบนี้ ฉันจะใช้วิธีนี้ได้อย่างไรถ้าชื่อคอลัมน์ของฉันมี '.' ในนั้น (เช่น 'ck.Class')? ขอบคุณ

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

28
นี่ไม่ได้ตอบคำถามที่ถาม
Aaron Schumacher

6
การนับจำนวนการสังเกตภายในแต่ละกลุ่มไม่ใช่ค่าเฉพาะของคอลัมน์ที่แน่นอนซึ่งแต่ละกลุ่มมี
Jason Goal

2
นี่คือคำตอบที่ไม่ถูกต้อง มันไม่สะท้อนDISTINCTความต้องการจากคำถาม! ยิ่งกว่านั้นไม่รวมถึงNaN!
คอเรย์เลวินสัน

47

ที่น่าสนใจพอมากมักจะlen(unique())เป็นไม่กี่ครั้ง (3x-15x) nunique()ได้เร็วกว่า


11
คุณหมายถึงอะไร .CLIENTCODE.apply(lambda x: len(x.unique())), จากที่นี่
user4015990

6
@ user32185 คุณจะต้องวางมันลงในการapplyโทรด้วยแลมบ์ดา df.groupby('YEARMONTH')['CLIENTCODE'].apply(lambda x: x.unique().shape[0])ยกตัวอย่างเช่น
3 พฤศจิกายน

3
ไวยากรณ์ไม่ชัดเจนอย่างสมบูรณ์ฉันlen(df['column'].unique())ไม่จำเป็นต้องใช้ฟังก์ชั่นแลมบ์ดา
mlh351

ฉันได้รับTypeError: object of type 'method' has no len()จากChen'sความคิดเห็น3novak'sทำงานให้ฉัน
Jason Goal

4

การใช้crosstabสิ่งนี้จะส่งคืนข้อมูลมากกว่าgroupby nunique

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

หลังจากปรับเปลี่ยนเล็กน้อยให้ผลลัพธ์

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

ฉันสามารถส่งออกนี้เป็นสองคอลัมน์และYEARMONTH countฉันสามารถตั้งค่าการนับตามลำดับจากมากไปน้อยได้หรือไม่
Murtaza Haji

3

ฉันกำลังใช้อยู่ด้วยnuniqueแต่มันจะมีประโยชน์มากถ้าคุณต้องใช้ฟังก์ชั่นรวมเช่น'min', 'max', 'count' or 'mean'ฯลฯ

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

นี่เป็นวิธีการนับที่แตกต่างกันในหลายคอลัมน์ มามีข้อมูลกันบ้าง:

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

ตอนนี้รายการคอลัมน์ที่น่าสนใจและใช้ groupby ในไวยากรณ์ปรับเปลี่ยนเล็กน้อย:

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

เราได้รับ:

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

0

ความแตกต่างของคอลัมน์พร้อมกับการรวมในคอลัมน์อื่น

เพื่อให้ได้จำนวนที่แตกต่างของค่าสำหรับคอลัมน์ใด ๆ ( CLIENTCODEในกรณีของคุณ) nuniqueเราสามารถใช้ เราสามารถส่งผ่านอินพุตเป็นพจนานุกรมในaggฟังก์ชันพร้อมกับการรวมในคอลัมน์อื่น ๆ :

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.