在各自的一键编码列中填充分类数据的值

时间:2018-12-17 13:35:06

标签: python pandas dataframe pivot one-hot-encoding

我有一个csv文件,其中包含100列和行。 我感兴趣的是两列,因此我需要在该csv文件中创建新的列。 例: 我有以下有趣的专栏, input.csv

 count  description    
    1   Good        
    2   Medium          
    2   Best        
    1   Worst       
    2   Worst       
    1   Medium      
    9   Good    

我期望的输出, output.csv

 count  description    Good  Medium  Best  Worst
    1   Good            1     0       0      0
    2   Medium          0     2       0      0
    2   Best            0     0       2      0
    1   Worst           0     0       0      1
    2   Worst           0     0       0      1
    1   Medium          0     1       0      0
    9   Good            9     0       0      0

在上面的csv表中,基于'count'和'description'的值。  我正在创建新列Good,Medium,Best,Worst(根据描述值),并填充count中的值,并将null设置为该行的不可用值。 我尝试比较列并映射值,但无法将值正确地放在新列中。

4 个答案:

答案 0 :(得分:2)

一种方法是使用pd.get_dummies创建虚拟列,并使用df['count] multiply创建虚拟列以获得所需的输出:

d = pd.get_dummies(df.description) 
df.assign(**d.multiply(df['count'], axis=0))

    count description  Best  Good  Medium  Worst
0      1        Good     0     1       0      0
1      2      Medium     0     0       2      0
2      2        Best     2     0       0      0
3      1       Worst     0     0       0      1
4      2       Worst     0     0       0      2
5      1      Medium     0     0       1      0
6      9        Good     0     9       0      0

答案 1 :(得分:2)

您可以旋转并添加原始框架:

f = df.pivot(columns='description', values='count').fillna(value=0, downcast='infer')
df[['count', 'description']].merge(f, left_index=True, right_index=True)

这将导致:

   count description  Best  Good  Medium  Worst
0      1        Good     0     1       0      0
1      2      Medium     0     0       2      0
2      2        Best     2     0       0      0
3      1       Worst     0     0       0      1
4      2       Worst     0     0       0      2
5      1      Medium     0     0       1      0
6      9        Good     0     9       0      0

答案 2 :(得分:2)

str.get_dummies

为了提高性能和简洁性,请将str.get_dummies与广播的numpy乘法一起使用。

v = df['description'].str.get_dummies()
df.join(pd.DataFrame(
    v.values * df['count'].values[:, None], columns=v.columns))


   count description  Best  Good  Medium  Worst
0      1        Good     0     1       0      0
1      2      Medium     0     0       2      0
2      2        Best     2     0       0      0
3      1       Worst     0     0       0      1
4      2       Worst     0     0       0      2
5      1      Medium     0     0       1      0
6      9        Good     0     9       0      0
  

我现在看到的是@nixon's answer的稍有不同的版本,但希望   请问广播方式的差异:-)


pivotfillna

或者,OP的pivot解决方案的修改版本:

df.join(df.reset_index()
          .pivot(index='index', columns='description', values='count')
          .fillna(0, downcast='infer'))

   count description  Best  Good  Medium  Worst
0      1        Good     0     1       0      0
1      2      Medium     0     0       2      0
2      2        Best     2     0       0      0
3      1       Worst     0     0       0      1
4      2       Worst     0     0       0      2
5      1      Medium     0     0       1      0
6      9        Good     0     9       0      0

答案 3 :(得分:1)

感谢您提供上述答案。 我还尝试了以下解决方案,

import pandas as pd
df = pd.read_csv('/input.csv')
res = df.pivot(index='index', columns='description', values='count')
res.to_csv('/out.csv',',',dtype='unicode8')
res1 = res.replace('NaN', '0', regex=True)
res1.to_csv('/out1.csv',',',dtype='unicode8')

谢谢, 桑达尔