简要说明:有一个similar question,最佳答案建议使用numpy.bincount
。我需要相同的东西,但对于矩阵。
我有两个阵列:
array([1, 2, 1, 1, 2])
array([2, 1, 1, 1, 1])
他们一起制作应递增的指数:
>>> np.array([a, b]).T
array([[1, 2],
[2, 1],
[1, 1],
[1, 1],
[2, 1]])
我想得到这个矩阵:
array([[0, 0, 0],
[0, 2, 1], # (1,1) twice, (1,2) once
[0, 2, 0]]) # (2,1) twice
矩阵很小(如5×5),索引数量很大(大约10 ^ 3或10 ^ 5)。
那么,有没有比for
更好(更快)的循环?
答案 0 :(得分:3)
您仍然可以使用bincount()
。诀窍是将a
和b
转换为单个1D平面索引数组。
如果矩阵为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]])
如果数组的形状更复杂,可能更容易使用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]])
(帽子提示@Jaime指出ravel_multi_index
。)
答案 1 :(得分:2)
m1 = m.view(numpy.ndarray) # Create view
m1.shape = -1 # Make one-dimensional array
m1 += np.bincount(a+m.shape[1]*b, minlength=m1.size)