大熊猫数据框中的一小部分值的频率

时间:2020-10-09 23:04:22

标签: python pandas dataframe dummy-variable

question提供了一个示例,说明如何使用pd.get_dummies +聚合从pandas数据帧中获取给定行的频率计数。但是,如果您只想从很大的数据框中只取一小部分字词,则无法缩放。

例如,考虑相同的示例:

import pandas as pd

df = pd.DataFrame({'ID': ['xyz_1', 'xyz_2', 'xyz_3', 'xyz_4', 'xyz_400'],
                   'class1': ['yes_1', 'no_2', pd.NA, 'no_3', 'no_7'],
                   'class2': ['no_8', 'yes_15', 'yes_16', 'no_18', 'no_21'],
                   'class3': [pd.NA, 'no_51', 'yes_1', 'no_3', 'no_4'],
                   'class100': ['yes_3', 'no_5', pd.NA, 'yes_6', 'no_7']})

        ID class1  class2 class3 class100
0    xyz_1  yes_1    no_8   <NA>    yes_3
1    xyz_2   no_2  yes_15  no_51     no_5
2    xyz_3   <NA>  yes_16  yes_1     <NA>
3    xyz_4   no_3   no_18   no_3    yes_6
4  xyz_400   no_7   no_21   no_4     no_7

这些值可以是许多不同类别变量之一,而不是是yes和no中的值。如果您只想为yes_1,no_51使用频率项,那么这将是大量的额外计算。

到目前为止,我发现的最佳解决方案是将其他值预处理为NANs

set = ['yes_1', 'no_51']
df[~df.isin(set)] = pd.NA

     ID class1 class2 class3 class100
0  <NA>  yes_1   <NA>   <NA>     <NA>
1  <NA>   <NA>   <NA>  no_51     <NA>
2  <NA>   <NA>   <NA>  yes_1     <NA>
3  <NA>   <NA>   <NA>   <NA>     <NA>
4  <NA>   <NA>   <NA>   <NA>     <NA>

对于大约100万个条目的大型数据帧而言,这仍然是冰冷的速度。有没有办法更好地扩展它。

3 个答案:

答案 0 :(得分:1)

我不知道它是否比您的技术更好,但我建议将其作为测试的解决方案:

(
    pd
    .melt(df,id_vars=['ID'])
    .assign(yes_1 = lambda x: np.where(x['value']=='yes_1',1,0))
    .assign(no_51 = lambda x: np.where(x['value']=='no_51',1,0))
    .sum()
)

答案 1 :(得分:1)

在链接的问题中,更有效的解决方案是:

df.apply(lambda row: row.value_counts(dropna=False), axis=1).fillna(0)

这可能已经足以满足您的目的;但是,如果只需要几个值,则可能会更快:

counts = pd.Series({(df == key).values.sum() for key in ['yes_1', 'no_51']}) 

答案 2 :(得分:1)

df.set_index('ID', inplace=True)#Set ID as index
df[~df.isin(['yes_1', 'no_51'])] = np.nan#Set anything not in the set as nan
pd.get_dummies(df.stack().unstack())#get dummies from a datframe that has dropped anycolumns with NaNS

      

              class1_yes_1  class3_no_51  class3_yes_1
ID                                             
xyz_1             1             0             0
xyz_2             0             1             0
xyz_3             0             0             1