我有以下数据帧:
+------------+------------------+
| 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]