假设我们有一个有多个客户的场景,每个客户可以购买不同数量的不同产品。下面的数据框说明了这一点——有多个id,每个id可以有不同的列值,如下所示:
id item No_Units No_Purchases
1 140 46 1
1 160 16 1
2 160 46 2
3 140 16 1
我们希望实现单行,这样我们就可以在单行上查看每个客户的购买。更新的数据框架应该基于以下条件:
- 项目列中的每个项目都应该有自己的列,类似于将其转换为虚拟变量。因此,item_140、item_160等。项目item_46中的内容将是项目编号46。如果客户没有选择该项目,则应将其分配为零。
- No_Units和no_purchase应该根据相关的项目列进行拆分-例如:No_Units_item_140,No_Units_item_160, No_Purchases_item_140, No_Purchases_item_160。
注意:除了上面显示的列外,还有多个列。输出Dataframe:
id item_140 item_160 No_Units_item_140 No_Purchases_140 No_Units_160 No_Purchases_160
1 140 160 46 1 16 2
2 0 160 0 0 46 2
3 140 0 16 1 0 0
代码的第一部分是创建虚拟变量:
df = pd.get_dummies(df, columns=['item'],drop_first=True, prefix=['item'])
我试图编码解决方案,但是有速度,标签,合并和插入原始值到虚拟数据帧的问题:
output = pd.DataFrame()
for customer in train_data['id'].unique():
df_user = df[df['id']==customer]
t = pd.DataFrame()
for feat in ['No_Units','No_Purchases']:
t = pd.DataFrame([df_user['item'],df_user[feat]]).T
t = pd.concat([t,t1],axis=1)
t=t.stack().to_frame().T
## t.columns = t.iloc[0]
t.columns = ['{}_{}'.format(*c) for c in t.columns]
t['id'] = df_user['id']
output = pd.concat([output,t],ignore_index=True)
我知道dict()也会大大加快这个速度。
可以使用pandas的pivot_table函数。你可以在这里了解到一切。https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.DataFrame.pivot_table.html
对于您的数据集,您可以使用以下代码:
df = df.pivot_table(['No_Units','No_Purchases','item'],'id','item_ind',fill_value=0)
df.columns =[s1 + str(s2) for (s1,s2) in df.columns.tolist()]
df.reset_index(inplace=True)
如果没有购买,它将用na填充列。您可以使用df.fillna(0)将它们更改为0。