【问题标题】:Numpy: increment elements of an array given the indices required to incrementNumpy:给定递增所需的索引,递增数组的元素
【发布时间】:2014-10-10 19:34:19
【问题描述】:

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

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

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

【问题讨论】:

  • 请显示示例输入和所需的输出。

标签: python arrays numpy


【解决方案1】:

您可以使用(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]]])

检查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])

表达式A[:,:,np.newaxis] == np.arange(A.max()+1) 使用broadcasting 将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])

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

只需稍作改动,这将适用于 n 维数组。用省略号 ... 索引一个 numpy 数组意味着“所有其他维度”。所以

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

将 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]])

【讨论】:

  • 非常感谢您的回答和解释。有时我会迷失在一些答案中,但您解释得非常清楚,再次感谢您。
【解决方案2】:

你可以这样工作:

tensor_3 = np.bincount(np.ravel_multi_index((a, b, array.reshape(x*y)),
                                            (x, y, np.amax(array) + 1)))

不同之处在于我将amax() 结果加1,因为ravel_multi_index() 期望索引都严格小于维度,而不是小于或等于。

我不能 100% 确定这是否是您想要的;使代码运行的另一种方法是在ravel_multi_index() 中指定mode='clip' 或mode='wrap',这有点不同,我猜不太正确。不过你可以试试。

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 2011-11-17
    • 2021-09-30
    • 1970-01-01
    • 2011-09-13
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多