Python 一个来自numpy的热编码

Python 一个来自numpy的热编码,python,numpy,one-hot-encoding,Python,Numpy,One Hot Encoding,我试图理解python示例输出的值。输出的顺序似乎是我能理解的。特定的python行给我带来了麻烦: vocab_size = 13 #just to provide all variable values m = 84 #just to provide all variable values Y_one_hot = np.zeros((vocab_size, m)) Y_one_hot[Y.flatten(), np.arange(m)] = 1 输入Y.flatte()的计算结果如下所

我试图理解python示例输出的值。输出的顺序似乎是我能理解的。特定的python行给我带来了麻烦:

vocab_size = 13   #just to provide all variable values
m = 84 #just to provide all variable values
Y_one_hot = np.zeros((vocab_size, m))
Y_one_hot[Y.flatten(), np.arange(m)] = 1
输入Y.flatte()的计算结果如下所示:

  [ 8  9  7  4  9  7  8  4  8  7  8 12  4  8  9  8 12  7  8  9  7 12  7  2
  9  7  8  7  2  0  7  8 12  2  0  8  8 12  7  0  8  6 12  7  2  8  6  5
  7  2  0  6  5 10  2  0  8  5 10  1  0  8  6 10  1  3  8  6  5  1  3 11
  6  5 10  3 11  5 10  1 11 10  1  3]
np排列是介于0-83之间的张量

np.arange(m)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
 72 73 74 75 76 77 78 79 80 81 82 83]
好的,我很难从新的Y_one_hot中理解的输出是,我收到了一个大小为13的numpy数组(如预期的),但我不理解为什么这些数组的位置位于基于Y.flatte()输入的位置,例如,这里是13的第一个数组:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
  0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0]
有人能解释一下我是如何从这一行中得到输入值到输出数组的吗?看起来一个是随机的,在其他13个数组中,一个的数量也是随机的。这是故意的行为吗

下面是一个完整的可运行示例:

import numpy as np
import sys
import re



# turn Y into one hot encoding
Y =  np.array([ 8,  9,  7,  4 , 9,  7,  8,  4,  8,  7,  8, 12,  4,  8,  9,  8, 12,  7,  8,  9,  7, 12,  7,  2,
  9,  7,  8,  7,  2,  0,  7,  8, 12,  2,  0,  8,  8, 12,  7,  0,  8,  6, 12,  7,  2,  8,  6,  5,
  7,  2,  0,  6,  5, 10,  2,  0,  8,  5, 10,  1,  0,  8,  6, 10,  1,  3,  8,  6,  5,  1,  3, 11,
  6,  5, 10,  3, 11,  5, 10,  1, 11, 10,  1,  3])
m = 84
vocab_size = 13
Y_one_hot = np.zeros((vocab_size, m))
Y_one_hot[Y.flatten(), np.arange(m)] = 1
np.set_printoptions(threshold=sys.maxsize)
print(Y_one_hot.astype(int))

Y\u one\u hot[Y.flatte(),np.arange(m)]=1
是设置带有整数索引列表的数组的值(记录在)

索引数组放在一起,一维数组的结果基本上是一种有效的方法:

对于zip中的i,j(Y.flatte(),np.arange(m)):
Y\u one\u hot[i,j]=1
换句话说,
Y\u one\u hot
的每一列对应于
Y.flatte()
的一个条目,并且在该条目给出的行中有一个非零值

使用较小的阵列可能更容易看到:

Y_onehot=np.zero((2,3),dtype=int)
Y=np.array([0,1,0])
Y_onehot[Y.flatte(),np.arange(3)]=1
打印(Y_onehot)
# [[1 0 1]
#  [0 1 0]]

三个条目映射到三列,每列对应于值的行中有一个非零条目。

您显示的代码是将多个标签索引转换为一个热编码的快速方法

让我们使用一个索引,并将其转换为一个热编码向量。为了简单起见,我们将坚持编码大小为10(即九个
0
s和一个
0
):

现在,让我们尝试使用多个索引:同时使用5个标签。起始数组将是二维的:
(5,10)
,即每个标签大小为10的一个热编码向量

>>> y = np.array([4, 2, 1, 7])
>>> y_ohe = np.zeros((4, 10))
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
预期的结果是:

array([[0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 7., 0., 0.]])
为此,我们将按行和列进行索引:
np.arange(len(y))
将为我们提供所有行索引,而
y
将为我们提供
1
应该位于的列。由于
np.arange(len(y))
y
具有相同的长度,它们将在压缩上迭代,类似于

>>> for i, j in zip(np.arange(len(y)), y):
>>>     print(i, j)
[0, 4]
[1, 2]
[2, 1]
[3, 7]
这些是2D张量
y_ohe
中的
[i,j]
坐标,我们希望
1
s在这里

将索引值分配给
1
s:

>>> y_ohe[np.arange(len(y)), y] = 1
array([[0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]])
类似地,通过另一种方法编制索引:

>>> y = np.array([4, 2, 1, 7])
>>> y_ohe = np.zeros((10, 4))
>>> y_ohe[y, np.arange(len(y))] = 1
array([[0., 0., 0., 0.],
       [0., 0., 1., 0.],
       [0., 1., 0., 0.],
       [0., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])


在您的例子中,
Y
有一个额外的维度,类似于
Y=np.array([[4]、[2]、[1]、[7]])
来关联我上面给出的示例。展平后将给出
y

y.flatte()
在第一维度中选择索引<代码>np.arange(m)正在选择第二维度的索引使用每个-
Y\u one\u hot[8,0]=1中的第一项这是预期的行为吗?
-您是在问为什么赋值表达式是这样工作的,还是在问这是否是进行编码的正确方法?从某种程度上说,我现在阅读答案是为了试图理解这种行为,但因为它完全适用于我发布的示例的价值观(但至少答案用最少的例子解释了这种行为。这是列的概念,似乎令人困惑,因为在发布的答案中,我可以理解为什么第一个数组的第四列中有一个1,但我的13×84 numpy数组的维数似乎让我困惑,第一个1值是如何在第30列中的。)第一个数组的列,因此我试图理解那里的系统…
np.vstack((Y,np.arange(m)).T
将向您显示索引是如何配对的。您可以看到第30个条目(
np.vstack((Y,np.arange(m))。T[29]
)是
[0,29]
。因此您的表达式为
Y\u one\u hot[0,29]赋值一个1
-如果这对你来说仍然没有意义,你需要花更多的时间来研究和玩弄这些例子-所以这不是一个教程。jakevdp答案中链接到的文档参考与你的问题相关。你可能想展示索引是如何配对的-所有的
[i,j]
来自您的示例….
np.vstack((Y,np.arange(m)).T
.OP仍然没有看到它。或者添加,
i,j在zip(Y.flatte(),np.arange(m)):print(f'Y_one_hot[{i},{j}]=1')
两个答案都很好地解释了问题,帮助我理解了值是如何分配的。加上二战的评论,我能够更容易地理解这个例子中发生的事情的逻辑,因此很难选择“正确答案”对于我的问题,我建议阅读这篇文章的人回顾这两个答案,因为它们都是有效的,因为我现在明白了发生的事情,这两个答案都是有意义的。
>>> y = np.array([4, 2, 1, 7])
>>> y_ohe = np.zeros((10, 4))
>>> y_ohe[y, np.arange(len(y))] = 1
array([[0., 0., 0., 0.],
       [0., 0., 1., 0.],
       [0., 1., 0., 0.],
       [0., 0., 0., 0.],
       [1., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 1.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])