【问题标题】:Grouping 2D numpy array in average平均分组 2D numpy 数组
【发布时间】:2011-06-05 04:16:19
【问题描述】:

我试图通过取元素的平均值将一个 numpy 数组分组为更小的大小。比如对一个 100x100 数组中的每个 5x5 子数组取平均值来创建一个 20x20 大小的数组。由于我需要处理大量数据,这是一种有效的方法吗?

【问题讨论】:

  • 也与this 回答类似。

标签: python numpy


【解决方案1】:

这很简单,虽然我觉得它可以更快:

from __future__ import division
import numpy as np
Norig = 100
Ndown = 20
step = Norig//Ndown
assert step == Norig/Ndown # ensure Ndown is an integer factor of Norig
x = np.arange(Norig*Norig).reshape((Norig,Norig)) #for testing
y = np.empty((Ndown,Ndown)) # for testing
for yr,xr in enumerate(np.arange(0,Norig,step)):
    for yc,xc in enumerate(np.arange(0,Norig,step)):
        y[yr,yc] = np.mean(x[xr:xr+step,xc:xc+step])

您可能还会发现scipy.signal.decimate 很有趣。它在对数据进行下采样之前应用了比简单平均更复杂的低通滤波器,尽管您必须先抽取一个轴,然后再抽取另一个。

【讨论】:

    【解决方案2】:

    我已经为较小的数组尝试过这个,所以用你的来测试一下:

    import numpy as np
    
    nbig = 100
    nsmall = 20
    big = np.arange(nbig * nbig).reshape([nbig, nbig]) # 100x100
    
    small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)
    

    6x6 -> 3x3 的示例:

    nbig = 6
    nsmall = 3
    big = np.arange(36).reshape([6,6])
    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],
           [24, 25, 26, 27, 28, 29],
           [30, 31, 32, 33, 34, 35]])
    
    small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)
    
    array([[  3.5,   5.5,   7.5],
           [ 15.5,  17.5,  19.5],
           [ 27.5,  29.5,  31.5]])
    

    【讨论】:

      【解决方案3】:

      在大小为 NxN 的子数组上平均一个二维数组:

      height, width = data.shape
      data = average(split(average(split(data, width // N, axis=1), axis=-1), height // N, axis=1), axis=-1)
      

      【讨论】:

      • 不错的一个!只是澄清平均和拆分是 numpy 函数。
      【解决方案4】:

      请注意,eumiro's approach 不适用于掩码数组,因为.mean(3).mean(1) 假定沿轴 3 的每个平均值都是根据相同数量的值计算的。如果您的数组中有被屏蔽的元素,则此假设不再成立。在这种情况下,您必须跟踪用于计算 .mean(3) 的值的数量,并用加权平均值替换 .mean(1)。权重是用于计算 .mean(3) 的标准化值数。

      这是一个例子:

      import numpy as np
      
      
      def gridbox_mean_masked(data, Nbig, Nsmall):
          # Reshape data
          rshp = data.reshape([Nsmall, Nbig//Nsmall, Nsmall, Nbig//Nsmall])
      
          # Compute mean along axis 3 and remember the number of values each mean
          # was computed from
          mean3 = rshp.mean(3)
          count3 = rshp.count(3)
      
          # Compute weighted mean along axis 1
          mean1 = (count3*mean3).sum(1)/count3.sum(1)
          return mean1
      
      
      # Define test data
      big = np.ma.array([[1, 1, 2],
                         [1, 1, 1],
                         [1, 1, 1]])
      big.mask = [[0, 0, 0],
                  [0, 0, 1],
                  [0, 0, 0]]
      Nbig = 3
      Nsmall = 1
      
      # Compute gridbox mean
      print gridbox_mean_masked(big, Nbig, Nsmall)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-28
        • 2012-12-23
        • 1970-01-01
        • 2015-05-31
        • 2021-04-22
        • 2016-11-20
        • 2018-06-02
        • 2021-05-15
        相关资源
        最近更新 更多