Numpy:给定递增所需的索引,递增数组的元素

use*_*415 4 python arrays numpy

我正在尝试将二阶张量转换为二元三阶张量。给定一个二阶张量作为 amxn numpy 数组:A,我需要取每个元素值:x,在 A 中并将其替换为向量:v,维度等于 A 的最大值,但值 1 递增在 v 对应于值 x 的索引处(即 v[x] = 1)。我一直在关注这个问题:Increment given indices in a matrix,它解决了在由二维坐标给出的索引处产生增量的数组。我一直在阅读答案并尝试使用 np.ravel_multi_index() 和 np.bincount() 来做同样的事情,但使用 3 维坐标,但是我不断收到 ValueError: "invalid entry in坐标数组"。这是我一直在使用的:

def expand_to_tensor_3(array):
    (x, y) = array.shape
    (a, b) = np.indices((x, y))
    a = a.reshape(x*y)
    b = b.reshape(x*y)
    tensor_3 = np.bincount(np.ravel_multi_index((a, b, array.reshape(x*y)), (x, y, np.amax(array))))
    return tensor_3
Run Code Online (Sandbox Code Playgroud)

如果您知道这里有什么问题或知道实现我的目标的更好方法,那么两者都会非常有帮助,谢谢。

War*_*ser 5

您可以使用(A[:,:,np.newaxis] == np.arange(A.max()+1)).astype(int).

这是一个演示:

In [52]: A
Out[52]: 
array([[2, 0, 0, 2],
       [3, 1, 2, 3],
       [3, 2, 1, 0]])

In [53]: B = (A[:,:,np.newaxis] == np.arange(A.max()+1)).astype(int)

In [54]: B
Out[54]: 
array([[[0, 0, 1, 0],
        [1, 0, 0, 0],
        [1, 0, 0, 0],
        [0, 0, 1, 0]],

       [[0, 0, 0, 1],
        [0, 1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1]],

       [[0, 0, 0, 1],
        [0, 0, 1, 0],
        [0, 1, 0, 0],
        [1, 0, 0, 0]]])
Run Code Online (Sandbox Code Playgroud)

检查 的几个单独元素A

In [55]: A[0,0]
Out[55]: 2

In [56]: B[0,0,:]
Out[56]: array([0, 0, 1, 0])

In [57]: A[1,3]
Out[57]: 3

In [58]: B[1,3,:]
Out[58]: array([0, 0, 0, 1])
Run Code Online (Sandbox Code Playgroud)

表达A[:,:,np.newaxis] == np.arange(A.max()+1)采用广播到的每个元素进行比较A,以np.arange(A.max()+1)。对于单个值,这看起来像:

In [63]: 3 == np.arange(A.max()+1)
Out[63]: array([False, False, False,  True], dtype=bool)

In [64]: (3 == np.arange(A.max()+1)).astype(int)
Out[64]: array([0, 0, 0, 1])
Run Code Online (Sandbox Code Playgroud)

A[:,:,np.newaxis]A形状的三维视图(3,4,1)。添加了额外的维度,以便比较 tonp.arange(A.max()+1)将广播到每个元素,给出带有 shape 的结果(3, 4, A.max()+1)

通过微不足道的更改,这将适用于 n 维数组。用省略号索引一个 numpy 数组...意味着“所有其他维度”。所以

(A[..., np.newaxis] == np.arange(A.max()+1)).astype(int)
Run Code Online (Sandbox Code Playgroud)

将 n 维数组转换为 (n+1) 维数组,其中最后一维是 中整数的二进制指示符A。下面是一个一维数组的例子:

In [6]: a = np.array([3, 4, 0, 1])

In [7]: (a[...,np.newaxis] == np.arange(a.max()+1)).astype(int)
Out[7]: 
array([[0, 0, 0, 1, 0],
       [0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)