5

我正在对具有大约 18 种不同值的分类列进行热编码。我只想为那些出现超过某个阈值(比如说 1%)的值创建新列,other values如果值不是那些频繁值,则创建另一个名为 1 的列。

我正在使用 Pandas 和 Sci-kit 学习。我已经探索了 pandasget_dummies和 sci-kit learn's one hot encoder,但不知道如何将不太频繁的值捆绑到一列中。

4

3 回答 3

4

计划

  • 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
于 2017-04-11T01:10:10.497 回答
3

像下面这样的东西怎么样:

创建数据框

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然后用这些计数替换实际值,以便将它们与阈值进行比较。将低于该阈值的值设置为“其他值”,然后用于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'
于 2017-04-11T00:15:42.253 回答
0
pip install siuba 
#( in python or anaconda prompth shell)

#use library as:
from siuba.dply.forcats import fct_lump, fct_reorder 

#just like fct_lump of R :

df['Your_column'] = fct_lump(df['Your_column'], n= 10)

df['Your_column'].value_counts() # check your levels

#it reduces the level to 10, lumps all the others as 'Other'

R 有一个很好的函数 fct_lump 用于此目的,现在它被复制到 python,只需选择要保留的级别数,所有其他级别将被捆绑为 'others' 。

于 2021-11-04T17:28:42.340 回答