【问题标题】:How to find most frequent values in numpy ndarray?如何在 numpy ndarray 中找到最常见的值?
【发布时间】:2012-08-31 02:13:09
【问题描述】:

我有一个形状为 (30,480,640) 的 numpy ndarray,第 1 轴和第 2 轴表示位置(纬度和经度),第 0 轴包含实际数据点。我想在每个轴上使用最常见的值位置,即构造一个形状为(1,480,640)的新数组。即:

>>> data
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]],

       [[40, 40, 42, 43, 44],
        [45, 46, 47, 48, 49],
        [50, 51, 52, 53, 54],
        [55, 56, 57, 58, 59]]])

(perform calculation)

>>> new_data 
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]]])

数据点将包含负数和正数浮点数。我怎样才能进行这样的计算?非常感谢!

我尝试使用 numpy.unique,但我得到“TypeError: unique() got an unexpected keyword argument 'return_inverse'”。我正在使用 Unix 上安装的 numpy 版本 1.2.1,它不支持 return_inverse..我也尝试过模式,但是处理如此大量的数据需要很长时间......那么有没有另一种方法来获得最频繁的值?再次感谢。

【问题讨论】:

  • 主导价值是什么意思?我不明白这个问题。
  • 我会支持@HenryGomersall 的评论 - 我也没有史酷比,你的问题是什么......
  • 对不起,您的困惑...我的意思是最常见的值..
  • 这能回答你的问题吗? Most efficient way to find mode in numpy array

标签: python numpy multidimensional-array


【解决方案1】:

我认为更好的解决方案如下

tmpL = np.array([3, 2, 3, 2, 5, 2, 2, 3, 3, 2, 2, 2, 3, 3, 2, 2, 3, 2, 3, 2])
unique, counts = np.unique(tmpL, return_counts=True)
return unique[np.argmax(counts)]

使用np.unique 我们可以获得每个唯一元素的计数。 counts 中最大元素的索引将是unique 中的对应元素。

【讨论】:

    【解决方案2】:

    解释@ecatmurs 部分

    u[np.argmax(np.apply_along_axis(np.bincount, axis, indices.reshape(arr.shape),
                                    None, np.max(indices) + 1), axis=axis)]
    

    多一点并在重新阅读时对其进行重组以使其更简洁(因为我使用了这个解决方案,几周后我想知道这个函数发生了什么):

    axis = 0
    uniques, indices = np.unique(arr, return_inverse=True)
    
    args_for_bincount_fn = None, np.max(indices) + 1
    binned_indices = np.apply_along_axis(np.bincount,
                                last_axis, 
                                indices.reshape(arr.shape),
                                *args_for_bincount_fn)
    
    most_common = uniques[np.argmax(binned_indices,axis=axis)]
    

    【讨论】:

      【解决方案3】:

      要查找平面数组的最频繁值,请使用uniquebincountargmax

      arr = np.array([5, 4, -2, 1, -2, 0, 4, 4, -6, -1])
      u, indices = np.unique(arr, return_inverse=True)
      u[np.argmax(np.bincount(indices))]
      

      要使用多维数组,我们不需要担心unique,但我们确实需要在bincount 上使用apply_along_axis

      arr = np.array([[5, 4, -2, 1, -2, 0, 4, 4, -6, -1],
                      [0, 1,  2, 2,  3, 4, 5, 6,  7,  8]])
      axis = 1
      u, indices = np.unique(arr, return_inverse=True)
      u[np.argmax(np.apply_along_axis(np.bincount, axis, indices.reshape(arr.shape),
                                      None, np.max(indices) + 1), axis=axis)]
      

      使用您的数据:

      data = np.array([
         [[ 0,  1,  2,  3,  4],
          [ 5,  6,  7,  8,  9],
          [10, 11, 12, 13, 14],
          [15, 16, 17, 18, 19]],
      
         [[ 0,  1,  2,  3,  4],
          [ 5,  6,  7,  8,  9],
          [10, 11, 12, 13, 14],
          [15, 16, 17, 18, 19]],
      
         [[40, 40, 42, 43, 44],
          [45, 46, 47, 48, 49],
          [50, 51, 52, 53, 54],
          [55, 56, 57, 58, 59]]])
      axis = 0
      u, indices = np.unique(arr, return_inverse=True)
      u[np.argmax(np.apply_along_axis(np.bincount, axis, indices.reshape(arr.shape),
                                      None, np.max(indices) + 1), axis=axis)]
      array([[ 0,  1,  2,  3,  4],
             [ 5,  6,  7,  8,  9],
             [10, 11, 12, 13, 14],
             [15, 16, 17, 18, 19]])
      

      NumPy 1.2,真的吗?您可以使用 np.searchsorted 合理有效地逼近 np.unique(return_inverse=True)(这是一个额外的 O(n log n),因此不应显着改变性能):

      u = np.unique(arr)
      indices = np.searchsorted(u, arr.flat)
      

      【讨论】:

      • @ecatmur,我使用的是 numpy 版本 1.2.1,它不支持 np.unique(return_inverse)..有什么建议吗?
      • @oops 见上文,你必须自己测试它,因为我什至不知道在哪里可以找到这么旧版本的 numpy ;)
      • 对于具有更多维度的大型 ndarray,这种方法并不适合,因为它会分配一个大小为 (N_dim1,N_dim2,...,N_unique) 的数组,很快就会失控。
      【解决方案4】:

      使用 SciPy 的 mode 函数:

      import numpy as np
      from scipy.stats import mode
      
      data = np.array([[[ 0,  1,  2,  3,  4],
                        [ 5,  6,  7,  8,  9],
                        [10, 11, 12, 13, 14],
                        [15, 16, 17, 18, 19]],
      
                       [[ 0,  1,  2,  3,  4],
                        [ 5,  6,  7,  8,  9],
                        [10, 11, 12, 13, 14],
                        [15, 16, 17, 18, 19]],
      
                       [[40, 40, 42, 43, 44],
                        [45, 46, 47, 48, 49],
                        [50, 51, 52, 53, 54],
                        [55, 56, 57, 58, 59]]])
      
      print data
      
      # find mode along the zero-th axis; the return value is a tuple of the
      # modes and their counts.
      print mode(data, axis=0)
      

      【讨论】:

      • 谢谢Taro Sato,但是处理大型数组需要很长时间。有什么建议可以加快速度吗?
      • 好的,我注意到你想用浮点数来做这个。为此,我认为您需要一种稍微不同的方法,因为询问最频繁的浮动是没有意义的,因为重复实验中两个浮动重合的可能性很小。你真的需要找到这么奇怪的东西吗?我您(大致)知道样本的分布,然后有更好的计算方法(例如均值和中位数)来找出样本中最可能的数字是多少。
      • 人们还在广泛使用 scipy 包吗?在某处读到 scipy 已被弃用。只是想知道:)
      • 写完这个答案已经有一段时间了,所以如果该功能已被弃用(例如支持np.mean),我不会感到惊讶......但我想我是在评论通用方法,而不是包的特定功能。
      【解决方案5】:

      flatten 你的数组,然后从它构建一个collections.Counter。像往常一样,在比较浮点数时要特别小心。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 2021-09-22
        • 1970-01-01
        • 2021-05-21
        • 1970-01-01
        • 2020-04-21
        • 1970-01-01
        相关资源
        最近更新 更多