将具有非唯一id和列值的数据框转换为每个唯一id的单行



假设我们有一个有多个客户的场景,每个客户可以购买不同数量的不同产品。下面的数据框说明了这一点——有多个id,每个id可以有不同的列值,如下所示:

id   item    No_Units     No_Purchases
1      140         46            1
1      160         16            1
2      160         46            2
3      140         16            1

我们希望实现单行,这样我们就可以在单行上查看每个客户的购买。更新的数据框架应该基于以下条件:

  1. 项目列中的每个项目都应该有自己的列,类似于将其转换为虚拟变量。因此,item_140、item_160等。项目item_46中的内容将是项目编号46。如果客户没有选择该项目,则应将其分配为零。
  2. 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。

最新更新