如何沿给定轴获取 numpy 数组中每个元素出现次数的逐元素计数?我所说的“按元素”是指数组的每个值都应转换为它出现的次数。
简单的二维输入:
[[1, 1, 1],
[2, 2, 2],
[3, 4, 5]]
应该输出:
[[3, 3, 3],
[3, 3, 3],
[1, 1, 1]]
该解决方案还需要相对于给定的轴工作。例如,如果我的输入数组 a
具有形状 (4, 2, 3, 3)
,我将其视为“3x3 矩阵的 4x2 矩阵”,运行 solution(a)
应该吐出上面形式的 (4, 2, 3, 3)
解决方案,其中每个 3x3
“子矩阵”包含相应元素相对于该子矩阵的计数,而不是整个 numpy 数组的计数。
更复杂的示例:假设我采用 a
上面的示例输入并调用 skimage.util.shape.view_as_windows(a, (2, 2))
。这给了我形状 (2, 2, 2, 2)
的数组 b
:
[[[[1 1]
[2 2]]
[[1 1]
[2 2]]]
[[[2 2]
[3 4]]
[[2 2]
[4 5]]]]
然后 solution(b)
应该输出:
[[[[2 2]
[2 2]]
[[2 2]
[2 2]]]
[[[2 2]
[1 1]]
[[2 2]
[1 1]]]]
因此即使值 1 在 a
中出现 3 次,在 b
中出现 4 次,它在每个 2x2
窗口中只出现两次。
最佳答案
出发进近
我们可以使用np.unique
获取出现次数并从 0
开始标记每个元素,让我们使用所需输出的标记对这些计数进行索引,就像这样 -
In [43]: a
Out[43]:
array([[1, 1, 1],
[2, 2, 2],
[3, 4, 5]])
In [44]: _,ids,c = np.unique(a, return_counts=True, return_inverse=True)
In [45]: c[ids].reshape(a.shape)
Out[45]:
array([[3, 3, 3],
[3, 3, 3],
[1, 1, 1]])
对于输入数组中的正整数,我们也可以使用np.bincount
-
In [73]: c = np.bincount(a.ravel())
In [74]: c[a]
Out[74]:
array([[3, 3, 3],
[3, 3, 3],
[1, 1, 1]])
对于负整数,简单地抵消其中的最小值。
扩展到通用 n-dims
让我们为此使用 bincount
-
In [107]: ar
Out[107]:
array([[[1, 1, 1],
[2, 2, 2],
[3, 4, 5]],
[[2, 3, 5],
[4, 3, 4],
[3, 1, 2]]])
In [104]: ar2D = ar.reshape(-1,ar.shape[-2]*ar.shape[-1])
# bincount2D_vectorized from https://stackoverflow.com/a/46256361/ @Divakar
In [105]: c = bincount2D_vectorized(ar2D)
In [106]: c[np.arange(ar2D.shape[0])[:,None], ar2D].reshape(ar.shape)
Out[106]:
array([[[3, 3, 3],
[3, 3, 3],
[1, 1, 1]],
[[2, 3, 1],
[2, 3, 2],
[3, 1, 2]]])
关于python - numpy 数组中沿值轴的逐元素计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47130141/