批量填充pandas中的虚拟变量列

时间:2018-05-01 21:48:49

标签: python pandas dummy-variable

我创建了一个独特的成员级数据框,如下所示:

memberid      codes       cost
memberA       {c1, c2}    100.0
memberB       {c2, c3}    120.0
memberC       {c1, c5}    200.0

codes的值是集合。我试图获得个别代码和成本之间的一些相关性,以便最终使用我拥有的其他一些功能构建预测模型。在熊猫之外我创建了一个Counter(),按流行度对代码进行排序:

all_codes = []
for entry in df['codes'].values:
    for code in entry:
        all_codes.append(code)

common_code_info = Counter(all_codes).most_common()
common_codes = [el[0] for el in common_code_info]

common_codes中总共有大约500个代码,我想创建相同数量的虚拟变量,但我不知道如何在Pandas中执行此操作。我试过像:

for code in common_codes:
    if code in df['codes'].values:
        df['has_'+code] = 1
    else:
        df['has_'+code] = 0

但它不起作用(所有虚拟列都是零)。是否有一种简单的方法来填充这些虚拟列,因为无法使用get_dummies,因为潜在虚拟变量的“源”位于数据帧之外?除非有一种更简单的方法来完成我正在寻找的只是使用Pandas的一切。

编辑: 代码是诊断代码,因此它们具有C801R911等值。结果数据框应如下所示:

memberid      codes       cost    has_c1    has_c2    has_c3
memberA       {c1, c2}    100.0   1         1         0
memberB       {c2, c3}    120.0   0         1         1
memberC       {c1, c5}    200.0   1         0         0

我也尝试过:

for code in common_codes:
    df['has_'+code] = np.where(code in df['codes'], 1, 0)

但这也不起作用。

示例数据帧的代码:

data = {'memberid': ['memberA', 'memberB', 'memberC'], 
        'codes': [{c1, c2}, {c2, c3}, {c1, c5}], 
        'cost': [100.0, 120.0, 200.0]}
df = pd.DataFrame(data, columns = ['memberid', 'codes', 'cost'])

1 个答案:

答案 0 :(得分:1)

一种方法是使用pd.get_dummies

稍微复杂的是,您需要先将set转换为list,因为get_dummies需要有序的收集。

import pandas as pd

data = {'memberid': ['memberA', 'memberB', 'memberC'], 
        'codes': [{'c1', 'c2'}, {'c2', 'c3'}, {'c1', 'c5'}], 
        'cost': [100.0, 120.0, 200.0]}

df = pd.DataFrame(data, columns = ['memberid', 'codes', 'cost'])

dummies = pd.get_dummies(df['codes'].apply(list).apply(pd.Series).stack()).sum(level=0)

res = df.join(dummies)

print(res)

  memberid     codes   cost  c1  c2  c3  c5
0  memberA  {c2, c1}  100.0   1   1   0   0
1  memberB  {c2, c3}  120.0   0   1   1   0
2  memberC  {c5, c1}  200.0   1   0   0   1