代码之家  ›  专栏  ›  技术社区  ›  Sociopath

如果在熊猫中计数小于阈值,则填充默认值

  •  3
  • Sociopath  · 技术社区  · 6 年前

    我有一个数据框架:

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame()
    df['name'] = ['john','sam','john','john','dean','dean','maggi',
                  'ram','maggi','ana','sam','sam']
    df['pt'] = [23, 32, 45, 65, 65, 45, 32, 45, 90, 10, 32, 22]
    

    如果名称在“名称”列中只出现一次,我想用“其他”替换名称。

    所以我的输出是:

         name  pt
    0    john  23
    1     sam  32
    2    john  45
    3    john  65
    4    dean  65
    5    dean  45
    6   maggi  32
    7   other  45
    8   maggi  90
    9   other  10
    10    sam  32
    11    sam  22
    

    在我的原始数据中,值以数百为单位,因此使用 df.replace map 不可行。

    np.where 仅适用于二进制列。所以我被困在这里。

    谢谢,

    2 回复  |  直到 6 年前
        1
  •  4
  •   jezrael    6 年前

    numpy.where duplicated transform size

    df['name'] = np.where(~df['name'].duplicated(keep=False), 'other', df['name'])
    

    df['name'] = np.where(df.groupby('name')['name'].transform('size') == 1, 'other', df['name'])
    print (df)
         name  pt
    0    john  23
    1     sam  32
    2    john  45
    3    john  65
    4    dean  65
    5    dean  45
    6   maggi  32
    7   other  45
    8   maggi  90
    9   other  10
    10    sam  32
    11    sam  22
    

    df.name.where(df.groupby('name')['name'].transform('size') > 1, 'other', inplace=True)
    
        2
  •  3
  •   jpp    6 年前

    pd.Series.value_counts pd.DataFrame.loc

    s = df['name'].value_counts(sort=False)
    df.loc[df['name'].isin(s[s == 1].index), 'name'] = 'other'
    
    print(df)
    
         name  pt
    0    john  23
    1     sam  32
    2    john  45
    3    john  65
    4    dean  65
    5    dean  45
    6   maggi  32
    7   other  45
    8   maggi  90
    9   other  10
    10    sam  32
    11    sam  22
    

    Categorical Data

    def jpp(df):
        s = df['name'].value_counts(sort=False)
        df.loc[df['name'].isin(s[s == 1].index), 'name'] = 'other'
        return df
    
    def jez(df):
        df['name'] = np.where(df.groupby('name')['name'].transform('size') == 1, 'other', df['name'])
        return df
    
    def jon(df):
        df['name'] = df['name'].apply(lambda name, counts=Counter(df['name']): name if counts[name] > 1 else 'other')
        return df
    
    assert jpp(df).equals(jez(df))
    assert jpp(df).equals(jon(df))
    
    %timeit jpp(df)  # 49.4 ms per loop
    %timeit jez(df)  # 56.2 ms per loop
    %timeit jon(df)  # 274 ms per loop
    

    df = pd.DataFrame({'name': ['john','sam','john','john','dean','dean','maggi',
                                'ram','maggi','ana','sam','sam'],
                       'pt': [23, 32, 45, 65, 65, 45, 32, 45, 90, 10, 32, 22]})
    
    df['name'] = df['name'].astype('category')
    df['name'] = df['name'].cat.add_categories('other')
    
    df = pd.concat([df, pd.concat([df.iloc[:5]]*100000)])