Pandas One热门编码:将频率较低的类别捆绑在一起

时间:2017-04-10 23:04:04

标签: python pandas scikit-learn one-hot-encoding

我正在对包含18种不同类型值的分类列进行一次热编码。我想只为这些值创建新列,这些值看起来超过某个阈值(假设为1%),并创建另一个名为other values的列,如果值不是那些频繁值,则列为1。

我正在使用Pandas和Sci-kit学习。我已经探索过大熊猫get_dummies和sci-kit learn's one hot encoder,但无法弄清楚如何将不常用的值捆绑到一列中。

2 个答案:

答案 0 :(得分:2)

计划

  • pd.get_dummies一个热门编码正常
  • sum() < threshold标识聚合的列
    • 我使用pd.value_counts参数normalize=True来获取出现的百分比。
  • join
def hot_mess2(s, thresh):
    d = pd.get_dummies(s)
    f = pd.value_counts(s, sort=False, normalize=True) < thresh
    if f.sum() == 0:
        return d
    else:
        return d.loc[:, ~f].join(d.loc[:, f].sum(1).rename('other'))

考虑pd.Series s

s = pd.Series(np.repeat(list('abcdef'), range(1, 7)))

s

0     a
1     b
2     b
3     c
4     c
5     c
6     d
7     d
8     d
9     d
10    e
11    e
12    e
13    e
14    e
15    f
16    f
17    f
18    f
19    f
20    f
dtype: object

hot_mess(s, 0)

    a  b  c  d  e  f
0   1  0  0  0  0  0
1   0  1  0  0  0  0
2   0  1  0  0  0  0
3   0  0  1  0  0  0
4   0  0  1  0  0  0
5   0  0  1  0  0  0
6   0  0  0  1  0  0
7   0  0  0  1  0  0
8   0  0  0  1  0  0
9   0  0  0  1  0  0
10  0  0  0  0  1  0
11  0  0  0  0  1  0
12  0  0  0  0  1  0
13  0  0  0  0  1  0
14  0  0  0  0  1  0
15  0  0  0  0  0  1
16  0  0  0  0  0  1
17  0  0  0  0  0  1
18  0  0  0  0  0  1
19  0  0  0  0  0  1
20  0  0  0  0  0  1

hot_mess(s, .1)

    c  d  e  f  other
0   0  0  0  0      1
1   0  0  0  0      1
2   0  0  0  0      1
3   1  0  0  0      0
4   1  0  0  0      0
5   1  0  0  0      0
6   0  1  0  0      0
7   0  1  0  0      0
8   0  1  0  0      0
9   0  1  0  0      0
10  0  0  1  0      0
11  0  0  1  0      0
12  0  0  1  0      0
13  0  0  1  0      0
14  0  0  1  0      0
15  0  0  0  1      0
16  0  0  0  1      0
17  0  0  0  1      0
18  0  0  0  1      0
19  0  0  0  1      0
20  0  0  0  1      0

答案 1 :(得分:1)

如下所示:

创建数据框

df = pd.DataFrame(data=list('abbgcca'), columns=['x'])
df

    x
0   a
1   b
2   b
3   g
4   c 
5   c
6   a

替换出现频率低于给定阈值的值。我将创建该列的副本,以便我不修改原始数据帧。第一步是创建value_counts的字典,然后用这些计数替换实际值,以便将它们与阈值进行比较。将低于该阈值的值设置为&#39;其他值&#39;然后使用pd.get_dummies获取虚拟变量

#set the threshold for example 20%
thresh = 0.2
x = df.x.copy()
#replace any values present less than the threshold with 'other values'
x[x.replace(x.value_counts().to_dict()) < len(x)*thresh] = 'other values'
#get dummies
pd.get_dummies(x)

        a       b       c       other values
    0   1.0     0.0     0.0     0.0
    1   0.0     1.0     0.0     0.0
    2   0.0     1.0     0.0     0.0
    3   0.0     0.0     0.0     1.0
    4   0.0     0.0     1.0     0.0
    5   0.0     0.0     1.0     0.0
    6   1.0     0.0     0.0     0.0

或者您可以使用Counter它可能更清洁

from collections import Counter
x[x.replace(Counter(x)) < len(x)*thresh] = 'other values'