GroupBy แพนด้า DataFrame และเลือกค่าที่พบบ่อยที่สุด


99

ฉันมีกรอบข้อมูลที่มีคอลัมน์สตริงสามคอลัมน์ ฉันรู้ว่าค่าเดียวในคอลัมน์ที่ 3 ใช้ได้กับทุกค่าผสมของสองค่าแรก ในการล้างข้อมูลฉันต้องจัดกลุ่มตามกรอบข้อมูลตามสองคอลัมน์แรกและเลือกค่าที่พบบ่อยที่สุดของคอลัมน์ที่สามสำหรับแต่ละชุดค่าผสม

รหัสของฉัน:

import pandas as pd
from scipy import stats

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
                  'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
                  'Short name' : ['NY','New','Spb','NY']})

print source.groupby(['Country','City']).agg(lambda x: stats.mode(x['Short name'])[0])

บรรทัดสุดท้ายของโค้ดใช้ไม่ได้มันขึ้นว่า "Key error" Short name "" และถ้าฉันพยายามจัดกลุ่มตามเมืองเท่านั้นฉันก็จะได้รับ AssertionError ฉันจะแก้ไขอะไรได้บ้าง?

คำตอบ:


145

คุณสามารถใช้value_counts()เพื่อรับชุดจำนวนและรับแถวแรก:

import pandas as pd

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
                  'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
                  'Short name' : ['NY','New','Spb','NY']})

source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])

ในกรณีที่คุณสงสัยเกี่ยวกับการทำงานของฟังก์ชัน agg อื่น ๆ ใน. agg () ให้ลองทำเช่นนี้

# Let's add a new col,  account
source['account'] = [1,2,3,3]

source.groupby(['Country','City']).agg(mod  = ('Short name', \
                                        lambda x: x.value_counts().index[0]),
                                        avg = ('account', 'mean') \
                                      )

ฉันพบว่า stats.mode สามารถแสดงคำตอบที่ไม่ถูกต้องในกรณีของตัวแปรสตริง วิธีนี้ดูน่าเชื่อถือกว่า
Viacheslav Nefedov

1
สิ่งนี้ไม่ควร.value_counts(ascending=False)?
ส่วนตัว

1
@Private: ascending=Falseเป็นค่าเริ่มต้นอยู่แล้วดังนั้นจึงไม่จำเป็นต้องกำหนดลำดับอย่างชัดเจน
Schmuddi

2
ดังที่ Jacquot กล่าวว่าpd.Series.modeตอนนี้เหมาะสมและเร็วกว่า
Daisuke SHIBATO

ฉันจะใช้โซลูชันนี้กับฟังก์ชันการรวมที่แตกต่างกันได้อย่างไรเช่นหากฉันมีหลายคอลัมน์เช่น "ชื่อย่อ" และคอลัมน์ตัวเลขเพิ่มเติมที่ฉันต้องการรวมกับฟังก์ชัน sum
constiii

99

นุ่น> = 0.16

pd.Series.mode สามารถใช้ได้!

การใช้งานgroupby, GroupBy.aggและใช้pd.Series.modeฟังก์ชั่นให้กับแต่ละกลุ่ม

source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

Country  City            
Russia   Sankt-Petersburg    Spb
USA      New-York             NY
Name: Short name, dtype: object

หากจำเป็นต้องใช้เป็น DataFrame ให้ใช้

source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode).to_frame()

                         Short name
Country City                       
Russia  Sankt-Petersburg        Spb
USA     New-York                 NY

สิ่งที่มีประโยชน์Series.modeคือมันจะส่งคืน Series เสมอทำให้เข้ากันได้ดีกับaggและapplyโดยเฉพาะอย่างยิ่งเมื่อสร้างเอาต์พุต groupby ขึ้นมาใหม่ มันเร็วกว่าด้วย

# Accepted answer.
%timeit source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])
# Proposed in this post.
%timeit source.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

5.56 ms ± 343 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.76 ms ± 387 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

การจัดการกับหลายโหมด

Series.modeยังทำงานได้ดีเมื่อมีหลายโหมด:

source2 = source.append(
    pd.Series({'Country': 'USA', 'City': 'New-York', 'Short name': 'New'}),
    ignore_index=True)

# Now `source2` has two modes for the 
# ("USA", "New-York") group, they are "NY" and "New".
source2

  Country              City Short name
0     USA          New-York         NY
1     USA          New-York        New
2  Russia  Sankt-Petersburg        Spb
3     USA          New-York         NY
4     USA          New-York        New

source2.groupby(['Country','City'])['Short name'].agg(pd.Series.mode)

Country  City            
Russia   Sankt-Petersburg          Spb
USA      New-York            [NY, New]
Name: Short name, dtype: object

หรือหากคุณต้องการแถวแยกต่างหากสำหรับแต่ละโหมดคุณสามารถใช้GroupBy.apply:

source2.groupby(['Country','City'])['Short name'].apply(pd.Series.mode)

Country  City               
Russia   Sankt-Petersburg  0    Spb
USA      New-York          0     NY
                           1    New
Name: Short name, dtype: object

หากคุณไม่สนใจว่าโหมดใดจะถูกส่งกลับตราบใดที่ยังเป็นโหมดใดโหมดหนึ่งคุณจะต้องใช้แลมบ์ดาที่เรียกmodeและดึงผลลัพธ์แรกออกมา

source2.groupby(['Country','City'])['Short name'].agg(
    lambda x: pd.Series.mode(x)[0])

Country  City            
Russia   Sankt-Petersburg    Spb
USA      New-York             NY
Name: Short name, dtype: object

ทางเลือกในการ (ไม่) พิจารณา

คุณยังสามารถใช้statistics.modeจาก python แต่ ...

source.groupby(['Country','City'])['Short name'].apply(statistics.mode)

Country  City            
Russia   Sankt-Petersburg    Spb
USA      New-York             NY
Name: Short name, dtype: object

... มันทำงานได้ไม่ดีเมื่อต้องจัดการกับหลายโหมด StatisticsErrorถูกยกขึ้น สิ่งนี้กล่าวถึงในเอกสาร:

หากข้อมูลว่างเปล่าหรือไม่มีค่าที่พบบ่อยที่สุดค่า StatisticsError จะเพิ่มขึ้น

แต่คุณสามารถเห็นด้วยตัวคุณเอง ...

statistics.mode([1, 2])
# ---------------------------------------------------------------------------
# StatisticsError                           Traceback (most recent call last)
# ...
# StatisticsError: no unique mode; found 2 equally common values

@JoshFriedlander df.groupby(cols).agg(pd.Series.mode)ดูเหมือนจะใช้ได้กับฉัน หากไม่ได้ผลการคาดเดาครั้งที่สองของฉันก็df.groupby(cols).agg(lambda x: pd.Series.mode(x).values[0])คือ
cs95

ขอบคุณ (เช่นเคย!) ตัวเลือกที่สองของคุณช่วยปรับปรุงสิ่งต่างๆให้ดีขึ้น แต่ฉันได้รับIndexError: index 0 is out of bounds for axis 0 with size 0(อาจเป็นเพราะมีกลุ่มที่ซีรีส์มีเฉพาะ NaN) การเพิ่มdropna=Falseจะช่วยแก้ปัญหานี้ได้ แต่ดูเหมือนว่าจะเพิ่มขึ้น'<' not supported between instances of 'float' and 'str'(ซีรี่ส์ของฉันเป็นสตริง) (ยินดีที่จะทำให้เป็นคำถามใหม่หากคุณต้องการ)
Josh Friedlander

2
@JoshFriedlander กำหนดdef foo(x): m = pd.Series.mode(x); return m.values[0] if not m.empty else np.nanแล้วใช้df.groupby(cols).agg(foo). หากไม่ได้ผลให้ใช้การดำเนินfooการสักหน่อย หากคุณยังคงประสบปัญหาอยู่ขอแนะนำให้เปิด Q ใหม่
cs95

1
ฉันควรเพิ่มว่าถ้าคุณต้องการรวมการนับnp.nanหนึ่งสามารถทำได้ผ่านdf.groupy(cols).agg(lambda x: x.mode(dropna=False).iloc[0])โหมดสมมติว่าคุณไม่สนใจความสัมพันธ์และต้องการเพียงโหมดเดียว
irene

17

สำหรับaggฟังก์ชัน lambba จะได้รับ a Seriesซึ่งไม่มี'Short name'แอตทริบิวต์

stats.mode ส่งคืนทูเปิลของสองอาร์เรย์ดังนั้นคุณต้องใช้องค์ประกอบแรกของอาร์เรย์แรกในทูเปิลนี้

ด้วยการเปลี่ยนแปลงง่ายๆสองอย่างนี้:

source.groupby(['Country','City']).agg(lambda x: stats.mode(x)[0][0])

ผลตอบแทน

                         Short name
Country City                       
Russia  Sankt-Petersburg        Spb
USA     New-York                 NY

1
@ViacheslavNefedov - ใช่ แต่ใช้วิธีแก้ปัญหาของ @ HYRY ซึ่งใช้แพนด้าบริสุทธิ์ ไม่จำเป็นต้องscipy.stats.
eumiro

14

เล่นเกมช้าไปหน่อยที่นี่ แต่ฉันพบปัญหาด้านประสิทธิภาพบางอย่างกับโซลูชันของ HYRY ดังนั้นฉันจึงต้องหาวิธีอื่น

ทำงานโดยการค้นหาความถี่ของแต่ละคีย์ - ค่าจากนั้นสำหรับแต่ละคีย์จะเก็บเฉพาะค่าที่ปรากฏบ่อยที่สุดเท่านั้น

นอกจากนี้ยังมีโซลูชันเพิ่มเติมที่รองรับหลายโหมด

ในการทดสอบมาตราส่วนซึ่งเป็นตัวแทนของข้อมูลที่ฉันกำลังทำงานอยู่นี้ลดรันไทม์จาก 37.4 วินาทีเป็น 0.5 วินาที!

นี่คือรหัสสำหรับโซลูชันตัวอย่างการใช้งานและการทดสอบมาตราส่วน:

import numpy as np
import pandas as pd
import random
import time

test_input = pd.DataFrame(columns=[ 'key',          'value'],
                          data=  [[ 1,              'A'    ],
                                  [ 1,              'B'    ],
                                  [ 1,              'B'    ],
                                  [ 1,              np.nan ],
                                  [ 2,              np.nan ],
                                  [ 3,              'C'    ],
                                  [ 3,              'C'    ],
                                  [ 3,              'D'    ],
                                  [ 3,              'D'    ]])

def mode(df, key_cols, value_col, count_col):
    '''                                                                                                                                                                                                                                                                                                                                                              
    Pandas does not provide a `mode` aggregation function                                                                                                                                                                                                                                                                                                            
    for its `GroupBy` objects. This function is meant to fill                                                                                                                                                                                                                                                                                                        
    that gap, though the semantics are not exactly the same.                                                                                                                                                                                                                                                                                                         

    The input is a DataFrame with the columns `key_cols`                                                                                                                                                                                                                                                                                                             
    that you would like to group on, and the column                                                                                                                                                                                                                                                                                                                  
    `value_col` for which you would like to obtain the mode.                                                                                                                                                                                                                                                                                                         

    The output is a DataFrame with a record per group that has at least one mode                                                                                                                                                                                                                                                                                     
    (null values are not counted). The `key_cols` are included as columns, `value_col`                                                                                                                                                                                                                                                                               
    contains a mode (ties are broken arbitrarily and deterministically) for each                                                                                                                                                                                                                                                                                     
    group, and `count_col` indicates how many times each mode appeared in its group.                                                                                                                                                                                                                                                                                 
    '''
    return df.groupby(key_cols + [value_col]).size() \
             .to_frame(count_col).reset_index() \
             .sort_values(count_col, ascending=False) \
             .drop_duplicates(subset=key_cols)

def modes(df, key_cols, value_col, count_col):
    '''                                                                                                                                                                                                                                                                                                                                                              
    Pandas does not provide a `mode` aggregation function                                                                                                                                                                                                                                                                                                            
    for its `GroupBy` objects. This function is meant to fill                                                                                                                                                                                                                                                                                                        
    that gap, though the semantics are not exactly the same.                                                                                                                                                                                                                                                                                                         

    The input is a DataFrame with the columns `key_cols`                                                                                                                                                                                                                                                                                                             
    that you would like to group on, and the column                                                                                                                                                                                                                                                                                                                  
    `value_col` for which you would like to obtain the modes.                                                                                                                                                                                                                                                                                                        

    The output is a DataFrame with a record per group that has at least                                                                                                                                                                                                                                                                                              
    one mode (null values are not counted). The `key_cols` are included as                                                                                                                                                                                                                                                                                           
    columns, `value_col` contains lists indicating the modes for each group,                                                                                                                                                                                                                                                                                         
    and `count_col` indicates how many times each mode appeared in its group.                                                                                                                                                                                                                                                                                        
    '''
    return df.groupby(key_cols + [value_col]).size() \
             .to_frame(count_col).reset_index() \
             .groupby(key_cols + [count_col])[value_col].unique() \
             .to_frame().reset_index() \
             .sort_values(count_col, ascending=False) \
             .drop_duplicates(subset=key_cols)

print test_input
print mode(test_input, ['key'], 'value', 'count')
print modes(test_input, ['key'], 'value', 'count')

scale_test_data = [[random.randint(1, 100000),
                    str(random.randint(123456789001, 123456789100))] for i in range(1000000)]
scale_test_input = pd.DataFrame(columns=['key', 'value'],
                                data=scale_test_data)

start = time.time()
mode(scale_test_input, ['key'], 'value', 'count')
print time.time() - start

start = time.time()
modes(scale_test_input, ['key'], 'value', 'count')
print time.time() - start

start = time.time()
scale_test_input.groupby(['key']).agg(lambda x: x.value_counts().index[0])
print time.time() - start

การเรียกใช้รหัสนี้จะพิมพ์สิ่งที่ต้องการ:

   key value
0    1     A
1    1     B
2    1     B
3    1   NaN
4    2   NaN
5    3     C
6    3     C
7    3     D
8    3     D
   key value  count
1    1     B      2
2    3     C      2
   key  count   value
1    1      2     [B]
2    3      2  [C, D]
0.489614009857
9.19386196136
37.4375009537

หวังว่านี่จะช่วยได้!


นั่นเป็นวิธีที่เร็วที่สุดที่ฉันมา .. ขอบคุณ!
FtoTheZ

1
มีวิธีใช้ aproach นี้ แต่อยู่ในพารามิเตอร์ agg โดยตรงหรือไม่เช่น. agg({'f1':mode,'f2':np.sum})
Pablo

1
@PabloA น่าเสียดายที่ไม่เพราะอินเทอร์เฟซไม่เหมือนกัน ฉันขอแนะนำให้ทำสิ่งนี้เป็นการดำเนินการแยกต่างหากจากนั้นจึงรวมผลลัพธ์ของคุณเข้าด้วยกันและแน่นอนว่าหากประสิทธิภาพไม่เป็นปัญหาคุณสามารถใช้โซลูชันของ HYRY เพื่อให้โค้ดของคุณมีความกระชับมากขึ้น
abw333

@ abw333 ฉันใช้โซลูชันของ HYRY แต่ฉันพบปัญหาด้านประสิทธิภาพ ... ฉันหวังว่าทีม dev ของแพนด้าจะสนับสนุนฟังก์ชันเพิ่มเติมในaggวิธีนี้
Pablo

เป็นวิธีที่แน่นอนในการใช้ DataFrames ขนาดใหญ่ ฉันมี 83 ล้านแถวและ 2.5 ล้านกลุ่มที่ไม่ซ้ำกัน ใช้เวลา 28 วินาทีต่อคอลัมน์ในขณะที่ agg ใช้เวลามากกว่า 11 นาทีต่อคอลัมน์
ALollz

5

คำตอบยอดนิยมสองข้อแนะนำ:

df.groupby(cols).agg(lambda x:x.value_counts().index[0])

หรือโดยเฉพาะอย่างยิ่ง

df.groupby(cols).agg(pd.Series.mode)

อย่างไรก็ตามทั้งสองข้อล้มเหลวในกรณีขอบธรรมดาดังที่แสดงไว้ที่นี่:

df = pd.DataFrame({
    'client_id':['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
    'date':['2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01', '2019-01-01'],
    'location':['NY', 'NY', 'LA', 'LA', 'DC', 'DC', 'LA', np.NaN]
})

ครั้งแรก:

df.groupby(['client_id', 'date']).agg(lambda x:x.value_counts().index[0])

ผลตอบแทนIndexError(เนื่องจากซีรี่ส์ว่างที่ส่งคืนโดยกลุ่มC) ที่สอง:

df.groupby(['client_id', 'date']).agg(pd.Series.mode)

ส่งคืนValueError: Function does not reduceเนื่องจากกลุ่มแรกส่งคืนรายการสองรายการ (เนื่องจากมีสองโหมด) (ตามเอกสารที่นี่หากกลุ่มแรกส่งคืนโหมดเดียวสิ่งนี้จะใช้ได้!)

สองวิธีที่เป็นไปได้สำหรับกรณีนี้คือ:

import scipy
x.groupby(['client_id', 'date']).agg(lambda x: scipy.stats.mode(x)[0])

และวิธีแก้ปัญหาที่มอบให้ฉันโดย cs95 ในความคิดเห็น ที่นี่ :

def foo(x): 
    m = pd.Series.mode(x); 
    return m.values[0] if not m.empty else np.nan
df.groupby(['client_id', 'date']).agg(foo)

อย่างไรก็ตามทั้งหมดนี้ช้าและไม่เหมาะกับชุดข้อมูลขนาดใหญ่ วิธีแก้ปัญหาที่ฉันใช้ซึ่ง a) สามารถจัดการกับกรณีเหล่านี้ได้และ b) เร็วกว่ามากคือคำตอบของ abw33 รุ่นที่ปรับเปลี่ยนเล็กน้อย (ซึ่งควรจะสูงกว่า):

def get_mode_per_column(dataframe, group_cols, col):
    return (dataframe.fillna(-1)  # NaN placeholder to keep group 
            .groupby(group_cols + [col])
            .size()
            .to_frame('count')
            .reset_index()
            .sort_values('count', ascending=False)
            .drop_duplicates(subset=group_cols)
            .drop(columns=['count'])
            .sort_values(group_cols)
            .replace(-1, np.NaN))  # restore NaNs

group_cols = ['client_id', 'date']    
non_grp_cols = list(set(df).difference(group_cols))
output_df = get_mode_per_column(df, group_cols, non_grp_cols[0]).set_index(group_cols)
for col in non_grp_cols[1:]:
    output_df[col] = get_mode_per_column(df, group_cols, col)[col].values

โดยพื้นฐานแล้วเมธอดจะทำงานบนหนึ่ง col ในแต่ละครั้งและส่งออก df ดังนั้นแทนที่จะconcatเป็นแบบเร่งรัดคุณถือว่าสิ่งแรกเป็น df จากนั้นเพิ่มอาร์เรย์เอาต์พุตซ้ำ ( values.flatten()) เป็นคอลัมน์ใน df


3

อย่างเป็นทางการคำตอบที่ถูกต้องคือ @eumiro Solution ปัญหาของการแก้ปัญหา @HYRY คือว่าเมื่อคุณมีลำดับของตัวเลขเช่น [1,2,3,4] วิธีการแก้ปัญหาที่ไม่ถูกต้องคือคุณไม่ได้มีโหมด ตัวอย่าง:

>>> import pandas as pd
>>> df = pd.DataFrame(
        {
            'client': ['A', 'B', 'A', 'B', 'B', 'C', 'A', 'D', 'D', 'E', 'E', 'E', 'E', 'E', 'A'], 
            'total': [1, 4, 3, 2, 4, 1, 2, 3, 5, 1, 2, 2, 2, 3, 4], 
            'bla': [10, 40, 30, 20, 40, 10, 20, 30, 50, 10, 20, 20, 20, 30, 40]
        }
    )

หากคุณคำนวณเช่น @HYRY คุณจะได้รับ:

>>> print(df.groupby(['client']).agg(lambda x: x.value_counts().index[0]))
        total  bla
client            
A           4   30
B           4   40
C           1   10
D           3   30
E           2   20

ซึ่งผิดชัดเจน (ดูค่าAที่ควรเป็น1ไม่ใช่4 ) เนื่องจากไม่สามารถจัดการกับค่าที่ไม่ซ้ำกันได้

ดังนั้นวิธีอื่นที่ถูกต้อง:

>>> import scipy.stats
>>> print(df.groupby(['client']).agg(lambda x: scipy.stats.mode(x)[0][0]))
        total  bla
client            
A           1   10
B           4   40
C           1   10
D           3   30
E           2   20

1

หากคุณต้องการแนวทางอื่นในการแก้ปัญหาที่ไม่ได้ขึ้นอยู่กับvalue_countsหรือscipy.statsคุณสามารถใช้Counterคอลเล็กชันได้

from collections import Counter
get_most_common = lambda values: max(Counter(values).items(), key = lambda x: x[1])[0]

ซึ่งสามารถนำไปใช้กับตัวอย่างข้างต้นเช่นนี้

src = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
              'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
              'Short_name' : ['NY','New','Spb','NY']})

src.groupby(['Country','City']).agg(get_most_common)

เร็วกว่าpd.Series.modeหรือpd.Series.value_counts().iloc[0]- แต่ถ้าคุณมีค่า NaN ที่คุณต้องการนับสิ่งนี้จะล้มเหลว น่านแต่ละเกิดขึ้นจะถูกมองว่าเป็นความแตกต่างจากแก่นแก้วอื่น ๆ 1เพื่อให้แต่ละน่านจะถูกนับที่จะมีการนับ ดูstackoverflow.com/questions/61102111/…
irene

1

หากคุณไม่ต้องการรวมค่า NaN การใช้Counterจะเร็วกว่าpd.Series.modeหรือpd.Series.value_counts()[0]:

def get_most_common(srs):
    x = list(srs)
    my_counter = Counter(x)
    return my_counter.most_common(1)[0][0]

df.groupby(col).agg(get_most_common)

ควรทำงาน. สิ่งนี้จะล้มเหลวเมื่อคุณมีค่า NaN เนื่องจากแต่ละ NaN จะถูกนับแยกกัน


0

ปัญหาที่นี่คือประสิทธิภาพหากคุณมีแถวจำนวนมากมันจะเป็นปัญหา

หากเป็นกรณีของคุณโปรดลองใช้สิ่งนี้:

import pandas as pd

source = pd.DataFrame({'Country' : ['USA', 'USA', 'Russia','USA'], 
              'City' : ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
              'Short_name' : ['NY','New','Spb','NY']})

source.groupby(['Country','City']).agg(lambda x:x.value_counts().index[0])

source.groupby(['Country','City']).Short_name.value_counts().groupby['Country','City']).first()

0

วิธีที่ง่ายกว่าเล็กน้อย แต่เร็วกว่าสำหรับชุดข้อมูลขนาดใหญ่คือการนับจำนวนคอลัมน์ที่น่าสนใจการเรียงลำดับการนับสูงสุดไปต่ำสุดจากนั้นการยกเลิกการทำซ้ำในชุดย่อยเพื่อเก็บเฉพาะกรณีที่ใหญ่ที่สุด ตัวอย่างโค้ดมีดังต่อไปนี้:

>>> import pandas as pd
>>> source = pd.DataFrame(
        {
            'Country': ['USA', 'USA', 'Russia', 'USA'], 
            'City': ['New-York', 'New-York', 'Sankt-Petersburg', 'New-York'],
            'Short name': ['NY', 'New', 'Spb', 'NY']
        }
    )
>>> grouped_df = source\
        .groupby(['Country','City','Short name'])[['Short name']]\
        .count()\
        .rename(columns={'Short name':'count'})\
        .reset_index()\
        .sort_values('count', ascending=False)\
        .drop_duplicates(subset=['Country', 'City'])\
        .drop('count', axis=1)
>>> print(grouped_df)
  Country              City Short name
1     USA          New-York         NY
0  Russia  Sankt-Petersburg        Spb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.