如何沿着给定轴获得每个元素在numpy数组中出现次数的元素计数?通过"元素方式,"我的意思是应该将数组的每个值转换为它出现的次数。
简单的2D输入:
[[1, 1, 1],
[2, 2, 2],
[3, 4, 5]]
应输出:
[[3, 3, 3],
[3, 3, 3],
[1, 1, 1]]
解决方案还需要相对于给定轴工作。例如,如果我的输入数组a
具有形状(4, 2, 3, 3)
,我认为它是" 3x3矩阵的3x3矩阵,"运行solution(a)
应该吐出上述表单的(4, 2, 3, 3)
解决方案,其中每个3x3
"子矩阵"包含相对于该子矩阵的相应元素的计数,而不是整个numpy数组。
更复杂的示例:假设我将示例输入放在a
上方并调用skimage.util.shape.view_as_windows(a, (2, 2))
。这为我提供了形状为b
的数组(2, 2, 2, 2)
:
[[[[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
窗口中仅出现两次。
答案 0 :(得分:3)
开始接近
我们可以使用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=1, return_inverse=1)
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]]])