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

batch-populate dummy variable columns in pandas

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

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

codes的值是集合。我试图在各个代码和成本之间获得一些相关性,以便最终使用我拥有的其他一些功能构建预测模型。在 Pandas 之外,我创建了一个 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 不能使用,因为潜在虚拟变量的 "source" 位于数据框之外?除非有更简单的方法来完成我正在寻找的一切,只需使用 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'])

一种方法是使用 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