【问题标题】:How to bin a 2D array in numpy?如何在 numpy 中对二维数组进行 bin 处理?
【发布时间】:2016-07-03 23:37:44
【问题描述】:

我是 numpy 的新手,我有一个 2D 对象数组,我需要将它们分箱到一个较小的矩阵中,然后计算每个箱中的对象数量以制作热图。我按照答案on this thread 创建了 bin 并计算了一个简单数组的计数,但我不确定如何将其扩展到二维。到目前为止,这是我所拥有的:

data_matrix = numpy.ndarray((500,500),dtype=float)
# fill array with values.

bins = numpy.linspace(0,50,50)
digitized = numpy.digitize(data_matrix, bins)

binned_data = numpy.ndarray((50,50))
for i in range(0,len(bins)):
    for j in range(0,len(bins)):
        k = len(data_matrix[digitized == i:digitized == j]) # <-not does not work
        binned_data[i:j] = k

附:数组上的[digitized == i] 表示法将返回二进制值数组。我在任何地方都找不到有关此表示法的文档。链接将不胜感激。

【问题讨论】:

  • 你能举一个简单的例子吗? 3*3 数组或类似的?我不明白你的目的。我不确定,也许你想看看np.histogram2d
  • 看看这个link

标签: python numpy matrix scipy


【解决方案1】:

另一个解决方案是在这里查看 cmets 上的 binArray 函数: Binning a numpy array

使用您的示例:

data_matrix = numpy.ndarray((500,500),dtype=float)
binned_data = binArray(data_matrix, 0, 10, 10, np.sum)
binned_data = binArray(binned_data, 1, 10, 10, np.sum)

data_matrix(大小为 500x500)中所有大小为 10x10 的正方形相加,得到 binned_data(大小为 50x50)中每个正方形的单个值。

希望有帮助!

【讨论】:

    【解决方案2】:

    您可以将数组重新整形为反映所需块结构的四维数组,然后沿每个块内的两个轴求和。示例:

    >>> a = np.arange(24).reshape(4, 6)
    >>> a
    array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11],
           [12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23]])
    >>> a.reshape(2, 2, 2, 3).sum(3).sum(1)
    array([[ 24,  42],
           [ 96, 114]])
    

    如果a 的形状为m, n,则reshape 的形状应为

    a.reshape(m_bins, m // m_bins, n_bins, n // n_bins)
    

    【讨论】:

      【解决方案3】:

      起初I was also going to suggest 认为您使用np.histogram2d 而不是重新发明轮子,但后来我意识到使用它会有点矫枉过正,并且仍然需要一些黑客攻击。

      如果我理解正确,您只想对输入的子矩阵求和。这很容易暴力破解:检查您的输出子矩阵并总结您输入的每个子块:

      import numpy as np
      
      def submatsum(data,n,m):
          # return a matrix of shape (n,m)
          bs = data.shape[0]//n,data.shape[1]//m  # blocksize averaged over
          return np.reshape(np.array([np.sum(data[k1*bs[0]:(k1+1)*bs[0],k2*bs[1]:(k2+1)*bs[1]]) for k1 in range(n) for k2 in range(m)]),(n,m))
      
      # set up dummy data
      N,M = 4,6
      data_matrix = np.reshape(np.arange(N*M),(N,M))
      
      # set up size of 2x3-reduced matrix, assume congruity
      n,m = N//2,M//3
      reduced_matrix = submatsum(data_matrix,n,m)
      
      # check output
      print(data_matrix)
      print(reduced_matrix)
      

      打印出来

      print(data_matrix)
      [[ 0  1  2  3  4  5]
       [ 6  7  8  9 10 11]
       [12 13 14 15 16 17]
       [18 19 20 21 22 23]]
      
      print(reduced_matrix)
      [[ 24  42]
       [ 96 114]]
      

      这确实是对形状为(2,3)的子矩阵求和的结果。

      请注意,我使用// 进行整数除法以确保它与python3 兼容,但对于python2,您可以只使用/ 进行除法(因为所涉及的数字是整数)。

      【讨论】:

      • 如果沿每个轴的 bin 数量是沿相应轴的维度的除数,则无需任何 Python 循环即可执行此操作(这会更快)。诀窍是将数组重塑为一个四维数组,然后沿右轴求和。
      • @SvenMarnach 你是对的,我一直忘记那个技巧:) 你想添加这个作为答案吗?
      • 完成。我昨天没有时间发布答案,所以我希望其他人可以这样做。
      猜你喜欢
      • 2015-09-04
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多