Numpy 如何对具有任意数量唯一值的向量进行热编码?

Numpy 如何对具有任意数量唯一值的向量进行热编码?,numpy,one-hot-encoding,Numpy,One Hot Encoding,给定一个输出向量y,该向量可以有任意数量的离散值,比如从集合{1,2,3,4}中。让向量具有以下实例: y = [1, 1, 2, 4, 2, 3, 1] 有没有一种numpy tonic库方法可以生成这个向量的一个热编码表示?即 y_enc = y1 y2 y3 y4 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 对于案例{0,1},我有一个小例子,但我看不出这是正确的方向: >

给定一个输出向量
y
,该向量可以有任意数量的离散值,比如从集合
{1,2,3,4}
中。让向量具有以下实例:

y = [1, 1, 2, 4, 2, 3, 1]
有没有一种numpy tonic库方法可以生成这个向量的一个热编码表示?即

y_enc =
y1 y2 y3 y4
1  0  0  0
1  0  0  0
0  1  0  0
0  0  0  1
0  1  0  0
0  0  1  0
1  0  0  0
对于案例{0,1},我有一个小例子,但我看不出这是正确的方向:

>>> k
array([[0.],
       [0.],
       [0.],
       [0.],
       [1.]])
>>> z = np.zeros((5,2))
>>> z
array([[0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.],
       [0., 0.]])
>>> for i,ki in enumerate(k):
...   if (ki == 0):
...     z[i][0] += 1
...   if (ki == 1):
...     z[i][1] += 1
... 
>>> z
array([[1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.]])
>>>

我发现最方便的方法是创建一个单位矩阵,并使用“花式索引”用
y
对其进行索引

现在
one_hot

array([[0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 1, 0],
       [0, 1, 0, 0, 0]], dtype=int32)
由于没有使用值
0
,因此可以通过执行

one_hot[:,1:]
输出:

array([[1, 0, 0, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 0]], dtype=int32)
这里有一种方法,基于选项
return\u inverse=True

In [67]: def onehot(a):
    ...:     u, inv = np.unique(a, return_inverse=True)
    ...:     n = len(a)
    ...:     result = np.zeros((n, len(u)), dtype=int)
    ...:     result[np.arange(n), inv] = 1
    ...:     return u, result
    ...: 

In [68]: y = [1, 1, 2, 4, 2, 3, 1]

In [69]: values, encoded = onehot(y)

In [70]: values
Out[70]: array([1, 2, 3, 4])

In [71]: encoded
Out[71]: 
array([[1, 0, 0, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 0]])

这是一个带有循环的解决方案:
np.hstack([y[:,None]==i,表示范围内的i(np.min(y),np.max(y)+1)])。astype(np.int32)
In [67]: def onehot(a):
    ...:     u, inv = np.unique(a, return_inverse=True)
    ...:     n = len(a)
    ...:     result = np.zeros((n, len(u)), dtype=int)
    ...:     result[np.arange(n), inv] = 1
    ...:     return u, result
    ...: 

In [68]: y = [1, 1, 2, 4, 2, 3, 1]

In [69]: values, encoded = onehot(y)

In [70]: values
Out[70]: array([1, 2, 3, 4])

In [71]: encoded
Out[71]: 
array([[1, 0, 0, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [1, 0, 0, 0]])