使用 pandas 中的多列获取 dummies/encoding

Getting dummies/encoding using multiple columns in pandas

我正在尝试为数据被分成多列的变量获取虚拟变量。

Input Data:
       fruit_1  fruit_2 fruit_3 fruit_4 fruit_5
Index                   
person1 Apple   NaN     NaN     NaN     NaN
person2 Apple   Banana  Guava   NaN     NaN
person3 Guava   NaN     NaN     NaN     NaN
person4 Banana  NaN     NaN     NaN     NaN
person5 Apple   Banana  Guava   Kiwi    Mango
person6 Kiwi    Mango   NaN     NaN     NaN

Desired Output:

           Apple    Banana  Guava   Kiwi    Mango
Index                   
person1        1    0       0      0        0
person2        1    1       1      0        0
person3        0    0       1      0        0
person4        0    1       0      0        0
person5        1    1       1      1        1
person6        0    0       0      1        1

在大多数方法中,我都尝试过 NaN/blank 导致问题,因为每行中的值的数量可以是 1 到 5 之间的任何值。我正在使用 pandas 来这样做.谢谢你的帮助。

所有列使用 get_dummies,聚合 max 重复的列名:

df = pd.get_dummies(df, prefix='', prefix_sep='').groupby(level=0, axis=1).max()
print (df)
         Apple  Banana  Guava  Kiwi  Mango
person1      1       0      0     0      0
person2      1       1      1     0      0
person3      0       0      1     0      0
person4      0       1      0     0      0
person5      1       1      1     1      1
person6      0       0      0     1      1

或者先按DataFrame.stackreshape,再按index聚合max,第一层:

df = pd.get_dummies(df.stack()).groupby(level=0).max()
print (df)
         Apple  Banana  Guava  Kiwi  Mango
person1      1       0      0     0      0
person2      1       1      1     0      0
person3      0       0      1     0      0
person4      0       1      0     0      0
person5      1       1      1     1      1
person6      0       0      0     1      1

一个选项是按行应用value_counts并填充任何空值

df.apply(pd.Series.value_counts, axis = 1).fillna(0, downcast='infer')

         Apple  Banana  Guava  Kiwi  Mango
Index
person1      1       0      0     0      0
person2      1       1      1     0      0
person3      0       0      1     0      0
person4      0       1      0     0      0
person5      1       1      1     1      1
person6      0       0      0     1      1

您可以做一个交叉表,这需要转换为长格式(上面的解决方案避免了一个步骤,希望能提供更高的效率):

 box = df.melt(ignore_index = False)

pd.crosstab(box.index, box.value)

value    Apple  Banana  Guava  Kiwi  Mango
row_0
person1      1       0      0     0      0
person2      1       1      1     0      0
person3      0       0      1     0      0
person4      0       1      0     0      0
person5      1       1      1     1      1
person6      0       0      0     1      1

请注意,交叉表并不是真的很快,但是很方便。