【问题标题】:Encoding a Dataframe differently than One-Hot以不同于 One-Hot 的方式编码数据帧
【发布时间】:2020-05-25 11:18:10
【问题描述】:

假设我有一个类似的 df 记录计算机游戏中 6 名玩家 (3v3) 中每个玩家的可玩角色选择。

data = {'Pick_1_team1': ['A','A','A','B','C'],
        'Pick_2_team1': ['D','D','E','F','F'],
        'Pick_3_team1': ['G','G','A','M','O'],
        'Pick_1_team2': ['Q','Q','S','S','A'],
        'Pick_2_team2': ['V','W','X','A','B'],
        'Pick_3_team2': ['R','X','W','W','R']}

df = pd.DataFrame(data)
df_enc = pd.get_dummies(df)

当我使用 panda 的 get_dummies 时,我会得到一个具有以下结构的稀疏 df(例如,不是示例 df 中的实际编码)

每个 Pick-slot 都有所有可能的选择 (A-Z),适用于两支球队。

| P1_T1_A | P1_T1_B | P1_T1_C | ... | P2_T1_A | ... | P3_T1_Z | ... | P1_T2_A | P1_T2_B | ... | P3_T2_Z |
|---------|---------|---------|-----|---------|-----|---------|-----|---------|---------|-----|---------|
| 0       | 0       | 1       | ... | 0       | ... | 0       | ... | 1       | 0       | ... | 1       |
| 1       | 0       | 0       | ... | 0       | ... | 0       | ... | 0       | 1       | ... | 1       |
| 1       | 0       | 0       | ... | 0       | ... | 0       | ... | 0       | 0       | ... | 0       |

这没关系,但如果您考虑更大的输入空间(有 150 多个可能的选择),表格会变得非常大。为了使其更易于管理,我正在考虑以某种方式将其编码为以下格式:

每个类别(角色)一列 x 每个团队 2,如果选择了该角色,则为 1,否则为 0。

| T1_A | T1_B | T1_C | ... | T1_Z | ... | T2_A | T2_B | ... | T2_Z |
|------|------|------|-----|------|-----|------|------|-----|------|
| 0    | 0    | 1    | ... | 0    | ... | 1    | 1    | ... | 1    |
| 1    | 1    | 1    | ... | 0    | ... | 0    | 0    | ... | 1    |
| 1    | 0    | 0    | ... | 0    | ... | 0    | 0    | ... | 0    |

这会将功能编号限制为选择数量 x 团队数量(26 个字母 * 2 个团队),而不是可能的选择 x 选择数量 x 团队数量(26 个字母 * 3 个选择 * 2 个团队) 熊猫可以通过任何内置函数做到这一点吗?如果不是,最简单的方法是什么?

任何帮助表示赞赏! 谢谢。

【问题讨论】:

  • 能否请您详细说明原始数据中的团队在哪里?只有选择和字母。
  • 谢谢,试过了。基本上 one.hot 的工作方式是将每个列拆分为 column+possible_categories。我想要的是将它重新排列为每个可能类别的一列(x 2 个团队),如果选择了该角色,则填充为 1。
  • @jezrael 没有错!我会接受这两种解决方案,但它不会让我。我能够将 Ben.T 解决方案推广到不同的 df。可能是因为我不习惯熊猫。
  • @jcf - 好的,我很惊讶,谢谢

标签: python pandas dataframe sparse-matrix one-hot-encoding


【解决方案1】:

您可以先选择一个包含filterstack 数据的团队并使用str.get_dummies,然后使用groupby level=0(原始df 中的行)和sumadd_prefixconcat 之前的列,两个团队都喜欢:

df_ = pd.concat([
            (df.filter(like=f'Pick_{i}').stack()
               .str.get_dummies()
               .groupby(level=0).sum()
               .add_prefix(f'T{i}_')
            ) for i in [1,2] ], 
            axis=1)
print (df_)
   T1_A  T1_B  T1_C  T1_D  T1_E  T1_F  T1_G  T1_M  T1_O  T2_A  T2_B  T2_Q  \
0     1     0     0     1     0     0     1     0     0     0     0     1   
1     1     0     0     1     0     0     1     0     0     0     0     1   
2     2     0     0     0     1     0     0     0     0     0     0     0   
3     0     1     0     0     0     1     0     1     0     1     0     0   
4     0     0     1     0     0     1     0     0     1     1     1     0   

   T2_R  T2_S  T2_V  T2_W  T2_X  
0     1     0     1     0     0  
1     0     0     0     1     1  
2     0     1     0     1     1  
3     0     1     0     1     0  
4     1     0     0     0     0  

【讨论】:

    【解决方案2】:

    如果只需要 1,0 值或 sum 如果需要计数值,则使用 get_dummies 和聚合 max

    df_enc = (pd.get_dummies(df.rename(columns=lambda x:x.split('_', 2)[-1].replace('team','T')))
                .max(axis=1, level=0)
                .sort_index(axis=1, level=0))
    print (df_enc)
       T1_A  T1_B  T1_C  T1_D  T1_E  T1_F  T1_G  T1_M  T1_O  T2_A  T2_B  T2_Q  \
    0     1     0     0     1     0     0     1     0     0     0     0     1   
    1     1     0     0     1     0     0     1     0     0     0     0     1   
    2     1     0     0     0     1     0     0     0     0     0     0     0   
    3     0     1     0     0     0     1     0     1     0     1     0     0   
    4     0     0     1     0     0     1     0     0     1     1     1     0   
    
       T2_R  T2_S  T2_V  T2_W  T2_X  
    0     1     0     1     0     0  
    1     0     0     0     1     1  
    2     0     1     0     1     1  
    3     0     1     0     1     0  
    4     1     0     0     0     0  
    

    【讨论】:

      猜你喜欢
      • 2017-02-16
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 2020-05-25
      • 2020-11-21
      • 2018-03-24
      • 2018-03-29
      • 2019-10-11
      相关资源
      最近更新 更多