【问题标题】:Get most common column for each column value获取每个列值的最常见列
【发布时间】:2017-11-08 07:01:27
【问题描述】:

我想要每个数字最常用的字母。我尝试了各种各样的东西;不知道什么是正确的方法。

import pandas as pd
from pandas import DataFrame, Series

original = DataFrame({
    'letter': {0: 'A', 1: 'A', 2: 'A', 3: 'B', 4: 'B'}, 
    'number': {0: '01', 1: '01', 2: '02', 3: '02', 4: '02'}
})

expected = DataFrame({'most_common_letter': {'01': 'A', '02': 'B'}})

理想情况下,我希望最大限度地提高可读性。

【问题讨论】:

    标签: python pandas split-apply-combine


    【解决方案1】:

    我们可以使用DataFrame.mode()方法:

    In [43]: df.groupby('number')[['letter']] \
               .apply(lambda x: x.mode()) \
               .reset_index(level=1, drop=True)
    Out[43]:
           letter
    number
    01          A
    02          B
    

    【讨论】:

      【解决方案2】:
      >>> df = pd.DataFrame({
          'letter': {0: 'A', 1: 'A', 2: 'A', 3: 'B', 4: 'B'}, 
          'number': {0: '01', 1: '01', 2: '02', 3: '02', 4: '02'}})
      >>> df['most_common_letter']=df.groupby('number')['letter'].transform(max) 
      >>> df = df.iloc[:,1:].drop_duplicates().set_index('number')
      >>> df.index.name = None
      >>> df
         most_common_letter
      01                  A
      02                  B
      

      如果它有助于提高可读性,也可以这样:

      >>> df['most_common_letter']=df.groupby('number')['letter'].transform(max) 
      >>> df = df.drop('letter', axis=1).drop_duplicates().rename({'number': None}).set_index('number')
      >>> df
         most_common_letter
      01                  A
      02                  B
      

      【讨论】:

        【解决方案3】:

        使用groupby + apply + value_counts + 选择第一个index 值,因为值已排序。

        最后转换Seriesto_frame并删除索引名称rename_axis

        df = original.groupby('number')['letter'] \
                     .apply(lambda x: x.value_counts().index[0])
                     .to_frame('most_common_letter')
                     .rename_axis(None)
        print (df)
           most_common_letter
        01                  A
        02                  B
        

        类似的解决方案:

        from collections import Counter
        
        df = original.groupby('number')['letter'] \
                     .apply(lambda x: Counter(x).most_common(1)[0][0]) \
                     .to_frame('most_common_letter') \
                     .rename_axis(None)
        print (df)
           most_common_letter
        01                  A
        02                  B
        

        或者使用Series.mode:

        df = original.groupby('number')['letter'] \
                     .apply(lambda x: x.mode()[0][0])
                     .to_frame('most_common_letter')
                     .rename_axis(None)
        print (df)
           most_common_letter
        01                  A
        02                  B
        

        【讨论】:

        • 有没有办法通过使用.idxmax() 或其他方式来提高可读性?
        • 不幸的是我现在不知道:(
        猜你喜欢
        • 2010-09-25
        • 1970-01-01
        • 2017-01-06
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多