简要地说:存在类似的问题,最佳答案建议使用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 更好(更快)的东西吗?
您仍然可以使用bincount()
. 诀窍是将a
和转换b
为平面索引的单个一维数组。
如果矩阵是n
x 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
。)