vectorize array:构造矩阵,指定位置为1,其他位置为0

vectorize array: construct matrix with 1 in specified places and 0 elsewhere

我有一个长度为 L 的(一维)numpy 数组 a,其中填充了从 0N-1
现在,我想构造一个 NxL 矩阵,使得在每一列 c 中,a[c]第一个条目是1,所有其他条目都是0.

例如,如果 L=4,N=5 并且

a = np.array([1,2,0,4])

然后我们想要一个矩阵

m = np.array([[0,0,1,0],
              [1,0,0,0],
              [0,1,0,0],
              [0,0,0,0],
              [0,0,0,1]])


现在,我有以下代码:

def vectorize(a, L, N):
    m = np.zeros((N, L))
    for (i,x) in enumerate(a):
        m[x][i] = 1.0

    return m

这很好用,但我确信有一个使用一些 numpy 技巧的更快的方法(避免循环遍历 a)。

您可以对第二个轴使用 np.arange(..)

def vectorize(a, L, N):
    m = np.zeros((N, L), int)
    m[a, np.arange(len(a))] = 1
    return m

因此对于给定的样本输入,我们得到:

>>> a = np.array([1,2,0,4])
>>> vectorize(a, 4, 5)
array([[0, 0, 1, 0],
       [1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 1]])

当您使用整数数组作为索引时,您需要广播到相同形状的其他数组来指示其他维度中的位置。在您的例子中, a 的每个元素都是一个行索引。对应栏目为:

b = np.arange(L)

现在你可以直接在矩阵中索引m:

m = np.zeros((N, L), dtype=bool)
m[a, b] = True

当你索引一个 numpy 数组时,你应该在一个括号运算符中使用所有索引,而不是像 m[a][b] 这样的单独运算符。当 a 是整数数组时,m[a]m 部分的副本,但当 a 是单个整数时,是原始数据的视图,即只有你的例子有效的原因。

def vectorize(a, L, N):
    m = np.zeros((N, L))
    m[a,np.arange(L)] =1
    return m