python - numpy 数组中沿值轴的逐元素计数

标签 python numpy scipy

如何沿给定轴获取 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/

相关文章:

c++ - 如何在 perforce 和 VMS 上对 C++ 进行代码审查/调试/编码/测试/版本控制

python - numpy的泊松置信区间

python - 如何对列表和 Numpy 数组进行列堆叠并保存txt?

python - 如何在时域计算基音基频f(0))?

python - 函数内部多处理 scipy 优化的奇怪行为

python - 无法检测到在 Ubuntu 上安装包的 Python 路径

python - 使用 * 参数从 sklearn 进行子类化的正确方法

python - 是否有用于分箱数据的 sci.stats.moment 函数?

python - 如何更改 jupyter 笔记本中的标准输入?

python - 广播高级索引 numpy