【问题标题】:Pandas non-numeric categorical dummy columns to single categorical columnPandas 将非数字分类虚拟列转换为单个分类列
【发布时间】:2020-06-10 07:52:10
【问题描述】:

我有如下数据

test=pd.DataFrame( {'group':['v','w','x','y','z'],
                       'cat1':['a',np.nan,np.nan,'c',np.nan],
                       'cat2':[np.nan,'b','a',np.nan,np.nan],
                       'cat3':[np.nan,np.nan,np.nan,np.nan,'a'],
                      })

我想做如下

| group | cat1 | cat2 | cat3 |
|-------|------|------|------|
|   v   |  a   | NaN  | NaN  |
|   w   | NaN  |  b   | NaN  |
|   x   | NaN  |  a   | NaN  |
|   y   |  c   | NaN  | NaN  |
|   z   | NaN  | NaN  |  a   |

| group | category | values |
|-------|----------|--------|
|   v   |   cat1   |   a    |
|   w   |   cat2   |   b    |
|   x   |   cat2   |   a    |
|   y   |   cat1   |   c    |
|   z   |   cat3   |   a    |

我尝试在 stackoverflow 的另一个问题中使用 idxmax,但这并没有成功。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以set_index 将“组”转换为索引,然后stack 删除NaN,然后​​您就完成了:

    test.set_index('group').stack()
    
    group      
    v      cat1    a
    w      cat2    b
    x      cat2    a
    y      cat1    c
    z      cat3    a
    dtype: object
    

    (test.set_index('group')
         .stack()
         .reset_index(name='values')
         .rename(columns={'level_1': 'categories'}))
    
      group categories values
    0     v       cat1      a
    1     w       cat2      b
    2     x       cat2      a
    3     y       cat1      c
    4     z       cat3      a
    

    注意:不对行进行排序


    另一个选项是使用pd.wide_to_long,产生类似的输出:

    (pd.wide_to_long(test, ['cat'], i=['group'], j='category')
       .dropna()
       .reset_index()
       .rename(columns={'cat': 'values'}))
    
      group  category values
    0     v         1      a
    1     y         1      c
    2     w         2      b
    3     x         2      a
    4     z         3      a
    

    注意:行将按“类别”排序

    【讨论】:

    • @Ch3steR 非常感谢您删除您的答案,这是意料之外的,但绝对值得赞赏 :-) 很高兴不时在这里见到体面的人。
    • 我以前用过很长代码的栈。现在你的解决方案看起来很苗条,特别是第二个答案。
    • 没问题,两个类似的答案无论如何都不会帮助社区。我发布它是因为我还没有看到你的帖子,否则我一开始就不会。我很自豪我采用了同样的方法。 :P
    【解决方案2】:

    您可以使用melt,删除空值并在variable 列上排序

    test.melt("group", var_name="category").dropna().sort_values("variable", ignore_index=True)
    
    
        group   variable    value
    0     v     cat1         a
    1     y     cat1         c
    2     w     cat2         b
    3     x     cat2         a
    4     z     cat3         a
    

    【讨论】:

    • 我喜欢融化。但我不需要排序。谢谢
    猜你喜欢
    • 2020-11-28
    • 1970-01-01
    • 2019-03-08
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2017-09-08
    相关资源
    最近更新 更多