Pandas one-hot-encode 列到傻瓜,包括“其他”编码

问题描述

我的最终目标是对 Pandas 列进行单热编码。 在这种情况下,我想按如下方式对列“b”进行单热编码:保留苹果、香蕉和橙子,并将任何其他水果编码为“其他”。

示例:在下面的代码中,“grapefruit”将被重写为“other”,如果“kiwi”和“avocado”出现在我的数据中,它们也会被重写。

以下代码有效:

df = pd.DataFrame({
    "a": [1,2,3,4,5],"b": ["apple","banana","orange","grapefruit"],"c": [True,False,True,True],})
print(df)

def analyze_fruit(s):
    if s in ("apple","orange"):
        return s
    else:
        return "other"

df['b'] = df['b'].apply(analyze_fruit)

df2 = pd.get_dummies(df['b'],prefix='b')
print(df2)

我的问题:是否有更短的方式来开展 analyze_fruit() 业务?我尝试了 DataFrame.replace(),但没有成功。

解决方法

您可以在 get_dummies 之前设置 Categorical 然后 fillna 任何与设置类别不匹配的内容都将变为 NaN 可以很容易地由 fillna 填充.分类的另一个好处是在这里也可以通过添加 ordered=True:

来定义排序
df['b'] = pd.Categorical(
    df['b'],categories=['apple','banana','orange','other']
).fillna('other')

df2 = pd.get_dummies(df['b'],prefix='b')

使用 np.where 之类的标准替换也可以在这里工作,但通常虚拟数据与分类数据一起使用,因此能够添加排序以便虚拟列以固定顺序出现可能会有所帮助:

# import numpy as np


df['b'] = np.where(df['b'].isin(['apple','orange']),df['b'],'other')

df2 = pd.get_dummies(df['b'],prefix='b')

两者都产生df2

   b_apple  b_banana  b_orange  b_other
0        1         0         0        0
1        0         1         0        0
2        0         1         0        0
3        0         0         1        0
4        0         0         0        1