【问题标题】:Pandas pivot out unique column熊猫转出独特的列
【发布时间】:2018-10-21 00:59:35
【问题描述】:

我有一个 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 值和数百万行。有什么想法吗?

【问题讨论】:

    标签: python pandas dataframe pivot dummy-variable


    【解决方案1】:

    pandas.get_dummies 来救援。

    pd.get_dummies(df.set_index(['A', 'B'])).reset_index()
    
            A   B  C_003  C_012  C_016  C_020  C_053
    0  000001  1A      1      0      0      0      0
    1  000001  1A      0      1      0      0      0
    2  000001  1C      0      0      1      0      0
    3  000001  1D      1      0      0      0      0
    4  000002  1A      0      0      0      1      0
    5  000002  1A      0      1      0      0      0
    6  000003  1D      0      0      0      0      1
    

    或者……(感谢温的提醒)

    pd.get_dummies(df.set_index(['A', 'B'])).sum(level=[0, 1]).reset_index()
    
            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
    

    【讨论】:

    • 第二个选项似乎工作得很好。谢谢!
    【解决方案2】:

    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
    

    【讨论】:

      【解决方案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
      

      通过使用strget_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
      

      【讨论】:

      • 我也记住了你最喜欢的功能。只是我在你之后把它放在我的帖子里,直到现在我才注意到它(-:.
      猜你喜欢
      • 1970-01-01
      • 2012-09-01
      • 2018-07-19
      • 2017-03-06
      • 2021-09-07
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      相关资源
      最近更新 更多