使用 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.stack
reshape,再按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
请注意,交叉表并不是真的很快,但是很方便。
我正在尝试为数据被分成多列的变量获取虚拟变量。
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.stack
reshape,再按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
请注意,交叉表并不是真的很快,但是很方便。