Binaryvectorize pandas数据帧列

2024-09-30 14:19:17 发布

您现在位置:Python中文网/ 问答频道 /正文

在虚构的患者数据集中,可能会遇到下表:

pd.DataFrame({
    "Patients": ["Luke", "Nigel", "Sarah"],
    "Disease": ["Cooties", "Dragon Pox", "Greycale & Cooties"]
})

将呈现以下数据集:

Fictional diseases

现在,假设有多个疾病的行使用相同的模式(用字符分隔,在这个上下文中是&),并且存在一个完整的疾病列表diseases,我还没有找到一个简单的解决方案来应用于这些情况^{}一个热编码器来获得每个患者的二进制向量。你知道吗

如何以最简单的方式从初始数据帧获得以下二进制矢量化?你知道吗

pd.DataFrame({
    "Patients": ["Luke", "Nigel", "Sarah"],
    "Cooties":[1, 0, 1],
    "Dragon Pox":[0, 1, 0],
    "Greyscale":[0, 0, 1]
})

Desired result


Tags: 数据患者dataframe二进制pd疾病lukedragon
3条回答

我们可以使用this函数将字符串取消到行。你知道吗

之后,我们将^{}aggfunc=len一起使用:

df = explode_str(df, 'Disease', ' & ')

print(df)
  Patients     Disease
0     Luke     Cooties
1    Nigel  Dragon Pox
2    Sarah    Greycale
2    Sarah     Cooties

df.pivot_table(index='Patients', columns='Disease', aggfunc=len)\
  .fillna(0).reset_index()

Disease Patients  Cooties  Dragon Pox  Greycale
0           Luke      1.0         0.0       0.0
1          Nigel      0.0         1.0       0.0
2          Sarah      1.0         0.0       1.0

链接答案中使用的函数:

def explode_str(df, col, sep):
    s = df[col]
    i = np.arange(len(s)).repeat(s.str.count(sep) + 1)
    return df.iloc[i].assign(**{col: sep.join(s).split(sep)})

方案1

您可以检查循环中diseasedf['Disease']的出现情况:

>>> diseases = ['Cooties', 'Dragon Pox', 'Greycale']
>>> for disease in diseases:
>>>     df[disease] = pd.Series(val == disease for val in df['Disease'].values).astype(int)

方案2

或者,在用'& '分割df['Disease']中的字符串之后,可以使用.get_dummies。你知道吗

>>> sub_df = df['Disease'].str.split('& ', expand=True)
>>> dummies = pd.get_dummies(sub_df)
>>> dummies

#    0_Cooties  0_Dragon Pox  0_Greycale   1_Cooties
# 0          1             0            0          0
# 1          0             1            0          0
# 2          0             0            1          1

# Let's rename the columns by taking only the text after the '_'
>>> _, dummies.columns = zip(*dummies.columns.str.split('_'))
>>> dummies.groupby(dummies.columns, axis=1).sum()

#      Cooties  Dragon Pox   Greycale 
#   0        1           0          0
#   1        0           1          0
#   2        1           0          1

可以使用Series.str.get_dummies和右分隔符

df.set_index('Patients')['Disease'].str.get_dummies(' & ').reset_index()

    Patients    Cooties Dragon Pox  Greycale
0   Luke        1       0           0
1   Nigel       0       1           0
2   Sarah       1       0           1

相关问题 更多 >