沿numpy数组中值的轴按元素计数 [英] element-wise count along axis of values in numpy array
问题描述
如何沿给定轴获得 numpy 数组中每个元素出现次数的元素计数?逐元素"是指数组的每个值都应该转换为它出现的次数.
How can I get an element-wise count of each element's number of occurrences in a numpy array, along a given axis? By "element-wise," I mean each value of the array should be converted to the number of times it appears.
简单的二维输入:
[[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 数组.
The solution also needs to work relative to a given axis. For example, if my input array a
has shape (4, 2, 3, 3)
, which I think of as "a 4x2 matrix of 3x3 matrices," running solution(a)
should spit out a (4, 2, 3, 3)
solution of the form above, where each 3x3
"submatrix" contains counts of the corresponding elements relative to that submatrix alone, rather than the entire numpy array at large.
更复杂的例子:假设我以 a
上面的例子输入并调用 skimage.util.shape.view_as_windows(a, (2, 2))
.这给了我形状 (2, 2, 2, 2)
:
More complex example: suppose I take the example input above a
and call skimage.util.shape.view_as_windows(a, (2, 2))
. This gives me array b
of shape (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
窗口中只出现两次.
So even though the value 1 occurs 3 times in a
and 4 times in b
, it only occurs twice in each 2x2
window.
推荐答案
入门方法
我们可以使用np.unique
获取出现次数,并从 0
开始标记每个元素,让我们用所需输出的标签索引这些计数,就像这样 -
We can use np.unique
to get the counts of occurrences and also tag each element from 0
onwards, letting us index into those counts with the tags for the desired output, like so -
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
-
For positive integers numbers in input array, we can also use 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]])
对于负整数,只需将其中的最小值偏移即可.
For negative integers numbers, simply offset by the minimum in it.
扩展到通用的 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]]])
这篇关于沿numpy数组中值的轴按元素计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!