在一行而不是多行中获取编码的分类变量

问题描述

我有与此

类似的原始数据框
my_df = pd.DataFrame({'uid': [4,3,6,4,1],'days': ['D1','D3','D4','D2','D2']})

  uid   days
0   4   D1
1   3   D3
2   6   D3
3   4   D4
4   3   D4


我使用了get_dummies()并得到了这种编码的数据框。

my_new_df = pd.get_dummies(my_df,columns=['days'])

uid days_D1 days_D2 days_D3 days_D4
0   4   1   0   0   0
1   3   0   0   1   0
2   6   0   0   1   0
3   4   0   0   0   1
4   3   0   0   0   1


我想要一个数据帧,其中所有分类值都为每个uid编码为一行。像这样

uid D1 D2 D3 D4
4    1  0  0 1
3    0  0  1 1
6    0  1  1 0
1    0  1  0 0


我试图寻找一种实现此结果的优化方法,但我无法做到这一点。我的原始数据框中有222000个值。请提出这样的编码分类变量方法

解决方法

您可以尝试在uid上进行分组,并在get_dummies之后获得其他列的最大值

(pd.get_dummies(my_df,columns=['days'],prefix='',prefix_sep='')
   .groupby('uid',sort=False).max())

或使用pivot替代:

my_df.pivot_table(index="uid",columns="days",aggfunc='size',fill_value=0)

     D1  D2  D3  D4
uid                
4     1   0   0   1
3     0   0   1   1
6     0   1   1   0
1     0   1   0   0
,

尝试此选项:

ss = pd.get_dummies(my_df,columns=['days']).groupby(['uid'],as_index=False).sum()
print(ss)

输出:

    uid days_D1 days_D2 days_D3 days_D4
0   1     0       1        0       0
1   3     0       0        1       1
2   4     1       0        0       1
3   6     0       1        1       0
,

您可以使用crosstab + clip

df = pd.crosstab(my_df['uid'],my_df['days']).clip(upper=1)

days  D1  D2  D3  D4
uid                 
1      0   1   0   0
3      0   0   1   1
4      1   0   0   1
6      0   1   1   0