【问题标题】:Target encoding multiple columns in pandas python目标编码熊猫python中的多列
【发布时间】:2022-11-25 10:57:24
【问题描述】:

我有下表。

id col1 col2 col3 col4  target
1    A    B  A    101   1
2    B    B  A    191   1
3    A    B  A     81   0 
4    C    B  C     67   1
5    B    C  C      3   0

我想对除col4 之外的每一列进行目标编码。

预期输出:

e1    e2     e3     target
0.5   0.75   0.667    1
0.5   0.75   0.667    1
0.5   0.75   0.667    0
1.0   0.75   0.5      1
0.5   0.00   0.5      0

编辑:对于 col1col2col3 的每一列,我都想获取目标编码。

例如,在 col3 中,A 出现 3 次,目标为 1 的 2/3 次。因此 A 的编码将为 0.667。类似地,对于 C,它在 col3 中为 0.5。

我已经为一个专栏尝试过这样的事情:

encodings = df.groupby('col1')['target'].mean().reset_index()
df = df.merge(encodings, how = 'left', on = 'col1')
df.drop('col1', axis = 1, inplace = TRUE)

【问题讨论】:

  • 道歉 - 我已经更新了输出。希望它更有意义。
  • 对于 col3,A 出现了 3/5 次,因此对于 e3,它将计算为 0.6。 C 出现了 2/5 次,因此对于 e3 它将计算为 0.4。相同的逻辑适用于 col2 和 col1。
  • 请注意,计算完全独立于target;)
  • 很抱歉我问错了问题并更新了示例输出。它实际上取决于目标。

标签: python pandas


【解决方案1】:
澄清后更新:

您需要使用与最初尝试相同的方法,但使用 map

df.update(df[['col1', 'col2', 'col3']]
          .apply(lambda s: s.map(df['target'].groupby(s).mean()))
          )

输出:

   id col1  col2      col3  col4  target
0   1  0.5  0.75  0.666667   101       1
1   2  0.5  0.75  0.666667   191       1
2   3  0.5  0.75  0.666667    81       0
3   4  1.0  0.75       0.5    67       1
4   5  0.5   0.0       0.5     3       0
OP 澄清之前的旧答案

IIUC,你想要map标准化的value_counts

df[['col1', 'col2', 'col3']].apply(lambda s: s.map(s.value_counts(normalize=True)))

输出:

   col1  col2  col3
0   0.4   0.8   0.6
1   0.4   0.8   0.6
2   0.4   0.8   0.6
3   0.2   0.8   0.4
4   0.4   0.2   0.4
更新数据到位:
df.update(df[['col1', 'col2', 'col3']]
          .apply(lambda s: s.map(s.value_counts(normalize=True)))
          )

更新的数据框:

   id col1 col2 col3  col4  target
0   1  0.4  0.8  0.6   101       1
1   2  0.4  0.8  0.6   191       1
2   3  0.4  0.8  0.6    81       0
3   4  0.2  0.8  0.4    67       1
4   5  0.4  0.2  0.4     3       0

【讨论】:

    【解决方案2】:

    您可以尝试使用 transform 和 for 循环

    l = [df.groupby(col)['target'].transform('mean') for col in ['col1','col2','col3']]
    out = pd.concat(l + [df.target],keys = ['e1','e2','e3','target'],axis=1)
    out
    Out[247]: 
        e1    e2        e3  target
    0  0.5  0.75  0.666667       1
    1  0.5  0.75  0.666667       1
    2  0.5  0.75  0.666667       0
    3  1.0  0.75  0.500000       1
    4  0.5  0.00  0.500000       0
    

    【讨论】:

      【解决方案3】:

      使用.apply。对于每一列 - 计算按此列分组的 target 的平均值:

      df[['col1', 'col2', 'col3']].apply(lambda s: s.map(df['target'].groupby(s).mean()))
      
         col1  col2      col3
      0   0.5  0.75  0.666667
      1   0.5  0.75  0.666667
      2   0.5  0.75  0.666667
      3   1.0  0.75  0.500000
      4   0.5  0.00  0.500000
      

      如果你还想有一个target列,你可以在最后使用.assign()

      df[['col1', 'col2', 'col3']].apply(lambda s: s.map(df['target'].groupby(s).mean())).assign(target=df['target'])
      
         col1  col2      col3  target
      0   0.5  0.75  0.666667       1
      1   0.5  0.75  0.666667       1
      2   0.5  0.75  0.666667       0
      3   1.0  0.75  0.500000       1
      4   0.5  0.00  0.500000       0
      

      笔记:.apply().transform() 在这里给出相同的结果。您可以用一个替换另一个。

      【讨论】:

        【解决方案4】:
        pd.concat([df1[col].map(pd.crosstab(df1[col],df1.target,normalize='index')[1]) for col in ['col1','col2','col3']],axis=1).join(df1.target)
            
              col1  col2      col3  target
            0   0.5  0.75  0.666667       1
            1   0.5  0.75  0.666667       1
            2   0.5  0.75  0.666667       0
            3   1.0  0.75  0.500000       1
            4   0.5  0.00  0.500000       0
        

        【讨论】:

          猜你喜欢
          • 2018-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-01
          • 1970-01-01
          • 2021-04-29
          • 2021-07-28
          • 2022-06-14
          相关资源
          最近更新 更多