【问题标题】:element-wise count along axis of values in numpy array沿numpy数组中值轴的元素计数
【发布时间】:2018-04-18 05:08:47
【问题描述】:

如何在给定的轴上获取 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) 解决方案,其中每个@ 987654328@ "submatrix" 包含相对于该子矩阵的相应元素的计数,而不是整个 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 窗口中仅出现两次。

【问题讨论】:

  • 详细说明 - element-wise count along axis of values in numpy array?你到底在数什么?
  • @Divakar 我想计算每个元素的出现次数。我将编辑问题以使其更清楚。与the question相关的你昨天聪明地回答了。
  • @CurtF。沿着相关轴循环并使用常规 python 循环构造一个新数组相当简单,但太慢了。我研究过使用 np.histogramnp.bincount,但它们似乎都不适合这项任务,因为它们需要扁平数组。

标签: python numpy scipy


【解决方案1】:

开始方法

我们可以使用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 维

让我们使用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]]])

【讨论】:

  • 太棒了!我刚刚编辑了我的帖子,为通用 n-dims 解决方案提供了一个示例。我将使用您的“通用 n-dims”解决方案玩几分钟,看看我是否可以按摩它以匹配我的示例。
  • @CaptainStiggz 为了提高性能,请尝试使用其他选项以及在该帖子中进行分箱计数 - stackoverflow.com/a/46256361
  • 这太棒了!您能否提出任何阅读建议,以更好地了解 numpy 基础知识?对于像我这样的 numpy 初学者来说,你正在做的一些重塑仍然感觉像是黑魔法。当涉及到更复杂的用例时,文档有点稀疏。例如,np.shape 上的 the docs 不覆盖负轴,就像您在 ar.reshape(-1,ar.shape[-2]*ar.shape[-1]) 中使用的那样
  • @CaptainStiggz ar.shape 是形状元组。而且,ar.shape[-1] 为我们提供了元组的最后一个元素,即数组最后一个轴的长度。 -2 是倒数第二个元素,因此是沿第二个轴的数组长度。我们的想法是我们需要获得沿最后两个轴的组合长度以进行整形。此外,ar.reshape(-1,..) 中的 -1 基本上意味着自动计算剩余长度,同时将重新整形的数组保持为 2D。供参考,我觉得官方文档还不错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-14
  • 2017-06-03
  • 2016-08-31
  • 2021-09-11
  • 2011-01-22
  • 2011-06-29
相关资源
最近更新 更多