熊猫转出独特的专栏

时间:2018-05-10 17:21:55

标签: python pandas dataframe pivot dummy-variable

我有一个pandas数据帧,其中有两个我认为是唯一标识符的组合,然后是一个可以有不同值的单个列'C'。因此,相同的唯一标识符可以重复与其具有的不同“C”值的数量一样多的次数。

import pandas as pd
data = {'A' : ['000001','000001','000001','000001','000002','000002','000003'],
       'B' : ['1A','1A','1C','1D','1A','1A','1D'],
       'C' : ['003','012','016','003','020','012','053']}

df = pd.DataFrame(data)

+-------------------+
| A      | B  | C   | 
+-------------------+
| 000001 | 1A | 003 |
| 000001 | 1A | 012 |
| 000001 | 1C | 016 |
| 000001 | 1D | 003 |
| 000002 | 1A | 020 |
| 000002 | 1A | 012 |
| 000003 | 1D | 053 |
+-------------------+

我想基于A,B对行进行分组,然后转出C列并将它们变成虚拟对象。这就是我需要最终输出的样子:

+----------------------------------------------------+
| A      | B  | C_003 | C_012 | C_016 | C_020 |C_053 |
+----------------------------------------------------+
| 000001 | 1A | 1     | 1     | 0     | 0     | 0    | 
| 000001 | 1C | 0     | 0     | 1     | 0     | 0    | 
| 000001 | 1D | 1     | 0     | 0     | 0     | 0    | 
| 000002 | 1A | 0     | 1     | 0     | 1     | 0    | 
| 000003 | 1D | 0     | 0     | 0     | 0     | 1    | 
+----------------------------------------------------+

我在数据透视表方面非常糟糕,但也不确定数据透视表是否可以使我达到我想要的输出。我正在寻找一个超级高效的过程,因为实际数据有更多列作为标识符的一部分(如A,B),数千个可能的C值和数百万行。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

groupbysize一起使用,重新设置为unstack,并按clip_upper过滤所有值1

df = (df.groupby(['A','B', 'C'])
      .size()
      .unstack(fill_value=0)
      .add_prefix('C_')
      .clip_upper(1)
      .reset_index())
print (df)
C       A   B  C_003  C_012  C_016  C_020  C_053
0  000001  1A      1      1      0      0      0
1  000001  1C      0      0      1      0      0
2  000001  1D      1      0      0      0      0
3  000002  1A      0      1      0      1      0
4  000003  1D      0      0      0      0      1

答案 1 :(得分:3)

你知道我记得我最喜欢的功能crosstab

pd.crosstab([df.A,df.B],df.C).reset_index()
Out[70]: 
C       A   B  003  012  016  020  053
0  000001  1A    1    1    0    0    0
1  000001  1C    0    0    1    0    0
2  000001  1D    1    0    0    0    0
3  000002  1A    0    1    0    1    0
4  000003  1D    0    0    0    0    1

使用str get_dummies

df.set_index(['A','B']).C.str.get_dummies().add_prefix('C_').sum(level=[0,1]).reset_index()
Out[60]: 
        A   B  C_003  C_012  C_016  C_020  C_053
0  000001  1A      1      1      0      0      0
1  000001  1C      0      0      1      0      0
2  000001  1D      1      0      0      0      0
3  000002  1A      0      1      0      1      0
4  000003  1D      0      0      0      0      1