【问题标题】:One-hot encoding across multiple columns - but as one group跨多列的单热编码 - 但作为一组
【发布时间】:2020-11-04 08:16:17
【问题描述】:

我有一个 Python Pandas 数据框:

Name Item1 Item2 Item3
John Sword
Mary Shield Ring
Doe  Ring Sword

期望的输出:

Name Item-Sword Item-Shield Item-Ring
John   1           0             0
Mary   0           1             1
Doe    1           0             1

这有什么方法可以在手动处理之外实现吗?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    使用get_dummies 和转换Name 列来索引并仅删除缺失值列,然后在输出中使用max0,1 值,添加前缀并将索引转换为列:

    df = (pd.get_dummies(df.set_index('Name')
                         .dropna(axis=1, how='all'), prefix='', prefix_sep='')
           .max(axis=1, level=0)
           .add_prefix('Item-')
           .reset_index())
    print (df)
       Name  Item-Ring  Item-Shield  Item-Sword
    0  John          0            0           1
    1  Mary          1            1           0
    2   Doe          1            0           1
    

    meltcrosstab 的替代方案 - @sammywemmy 解决方案,drop_duplicates

    df1 = (df.melt("Name")
            .assign(value=lambda x: "Item-" + x.value)
            .drop_duplicates(['Name','value']))
    df1 = pd.crosstab(df1.Name, df1.value)
    print (df1)
    value  Item-Ring  Item-Shield  Item-Sword
    Name                                     
    Doe            1            0           1
    John           0            0           1
    Mary           1            1           0
    

    【讨论】:

      【解决方案2】:

      DataFrame.melt + DataFrame.groupby 的另一种解决方案

      new_df = (df.melt('Name').groupby(['Name', 'value'])
                  .count()
                  .clip(0, 1)
                  .unstack('value', fill_value=0)
                  .droplevel(0, axis=1)
                  .add_prefix('Item-')
                  .rename_axis(columns=None)
                  .reset_index())
      print(new_df)
      

      DataFrame.pivot_table

      df2 = df.melt('Name')
      new_df = (df2.pivot_table(index='Name', columns='value', values='variable', 
                                aggfunc='any', fill_value=0)
                   .astype(int)
                   .add_prefix('Item-')
                   .rename_axis(columns=None)
                   .reset_index())
      print(new_df)
      

      输出

         Name  Item-Ring  Item-Shield  Item-Sword
      0   Doe          1            0           1
      1  John          0            0           1
      2  Mary          1            1           0
      

      【讨论】:

      • 现在检查:) @jezrael
      • 是的,现在更好
      【解决方案3】:

      如果将索引设置为"Name",然后将stack() 数据设置为单个Series,则可以使用pd.get_dummies 对数据进行编码。然后你需要使用max 来获得每个"Name" 的最大值(这个逻辑归结为:我们不关心"Mary" 是否有一个环作为项目1 或项目2,只要她有一个环)。完成后,我们可以通过添加前缀并将索引重置回DataFrame来进行整理

      out = (df.set_index("Name")
             .stack()
             .pipe(pd.get_dummies)
             .max(level="Name")
             .add_prefix("Item-")
             .reset_index())
      
      print(out)
         Name  Item-Ring  Item-Shield  Item-Sword
      0  John          0            0           1
      1  Mary          1            1           0
      2   Doe          1            0           1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-18
        • 2021-02-11
        • 1970-01-01
        • 1970-01-01
        • 2019-11-06
        • 2021-01-06
        • 1970-01-01
        • 2019-08-12
        相关资源
        最近更新 更多