pandas | list in column to binary column



我有以下数据帧:

+------------+------------------+
| item       | categories       |
+------------+------------------+
| blue_shirt | ['red', 'white'] |
+------------+------------------+
| red_skirt  | ['blue', 'red']  |
+------------+------------------+

我想得到这个:

+------------+-----+-------+------+
| item       | red | white | blue |
+------------+-----+-------+------+
| blue_shirt | 1   | 1     | 0    |
+------------+-----+-------+------+
| red_skirt  | 1   | 0     | 1    |
+------------+-----+-------+------+

这是我试过的:

orders = orders.join(pd.get_dummies(orders['Categories'].explode()))

它创建了正确的列,但也创建了(很多(额外的行。我希望每个项目的末尾都有一行,就像上面的例子一样。

您也可以使用pandas 的.str方法用一行代码来解决这个问题

df['categories'].str.join('|').str.get_dummies()

"类别">列的每个单元格中的格式都需要是列表。如果它是其他东西的字符串,则可以使用.apply函数使其成为列表。例如,如果"类别">列的内容是保存为字符串的列表:

df['categories'].apply(lambda x: eval(x)).str.join('|').str.get_dummies()

您可以分解类别并透视数据帧:

print(
df.explode("categories")
.pivot_table(
index="item", columns="categories", aggfunc="size", fill_value=0
)
.reset_index()
)

打印:

categories        item  blue  red  white
0           blue_shirt     0    1      1
1            red_skirt     1    1      0

我能够通过以下方法获得您想要的结果。

步骤1:创建将在生成的数据集中使用的列列表。

>>> cols = list(set(df['categories'].explode())) #set makes sure we keep unique columns
>>> cols.insert(0,df.columns[0]) 
cols
Out[359]: ['item', 'red', 'white', 'blue']

可选:您可以通过将列转换为列表类型来确保explode()工作:从这里

from ast import literal_eval
df['categories'] = df['categories'].apply(literal_eval) # convert to list type

步骤2:将代码与pd.get_dummies()一起使用,并创建1/0数据集。为了避免得到更多的行,我使用groupby.index:添加了一个额外的步骤

>>> temp = pd.get_dummies(df['categories'].explode())
>>> temp_res = temp.groupby(temp.index).sum()
Out[365]: 
blue  red  white
0     0    1      1
1     1    1      0

步骤3:,我concat您的"项目"列,并使用第一步中创建的列列表来获得您想要的结果:

>>> out = pd.concat([df['item'],temp_res],axis=1,ignore_index=False)
>>> out = out[cols]
Out[368]: 
item  red  white  blue
0  blue_shirt    1      1     0
1   red_skirt    1      0     1

1个块中的所有代码

from ast import literal_eval
df['categories'] = df['categories'].apply(literal_eval) #convert to list type
cols = list(set(df['categories'].explode()))
cols.insert(0,df.columns[0]) 
temp = pd.get_dummies(df['categories'].explode())
temp_res = temp.groupby(temp.index).sum()
out = pd.concat([df['item'],temp_res],axis=1)
out = out[cols]

最新更新