矩阵中给定索引的增量

kir*_*gin 5 python numpy

简要地说:存在类似的问题,最佳答案建议使用numpy.bincount。我需要同样的东西,但需要一个矩阵。

我有两个数组:

array([1, 2, 1, 1, 2])
array([2, 1, 1, 1, 1])
Run Code Online (Sandbox Code Playgroud)

它们共同构成应增加的索引:

>>> np.array([a, b]).T
array([[1, 2],
       [2, 1],
       [1, 1],
       [1, 1],
       [2, 1]])
Run Code Online (Sandbox Code Playgroud)

我想得到这个矩阵:

array([[0, 0, 0],
       [0, 2, 1],  # (1,1) twice, (1,2) once
       [0, 2, 0]]) # (2,1) twice
Run Code Online (Sandbox Code Playgroud)

矩阵将很小(例如5×5),索引的数量将很大(大约10 ^ 3或10 ^ 5)。

那么,有什么比for-loop 更好(更快)的东西吗?

NPE*_*NPE 4

您仍然可以使用bincount(). 诀窍是将a和转换b为平面索引的单个一维数组。

如果矩阵是nx m,您可以应用bincount()a * m + b并根据结果构造矩阵。

以你问题中的例子为例:

In [15]: a = np.array([1, 2, 1, 1, 2])

In [16]: b = np.array([2, 1, 1, 1, 1])

In [17]: cnt = np.bincount(a * 3 + b)

In [18]: cnt.resize((3, 3))

In [19]: cnt
Out[19]: 
array([[0, 0, 0],
       [0, 2, 1],
       [0, 2, 0]])
Run Code Online (Sandbox Code Playgroud)

如果数组的形状更复杂,使用它可能np.ravel_multi_index()比手动计算平面索引更容易:

In [20]: cnt = np.bincount(np.ravel_multi_index(np.vstack((a, b)), (3, 3)))

In [21]: np.resize(cnt, (3, 3))
Out[21]: 
array([[0, 0, 0],
       [0, 2, 1],
       [0, 2, 0]])
Run Code Online (Sandbox Code Playgroud)

(向@Jaime 致敬,指出了这一点ravel_multi_index。)

  • +1 非常好。[`np.ravel_multi_index`](http://docs.scipy.org/doc/numpy/reference/ generated/numpy.ravel_multi_index.html) 可能会派上用场,以避免对更复杂的数组考虑太多。 (3认同)