【问题标题】:Numpy rebinning a 2D arrayNumpy 重新组合二维数组
【发布时间】:2013-02-01 17:13:07
【问题描述】:

我正在寻找一种快速公式来对 2D numpy 数组进行数值分箱。通过分箱,我的意思是计算子矩阵平均值或累积值。例如。 x = numpy.arange(16).reshape(4, 4) 将被分成 4 个 2x2 的子矩阵,并给出 numpy.array([[2.5,4.5],[10.5,12.5]]) 其中 2.5=numpy。平均([0,1,4,5])等...

如何以有效的方式执行这样的操作...我真的不知道如何执行此操作...

非常感谢...

【问题讨论】:

  • 是否保证子矩阵完全适合?你有numpy 1.7吗?可用(那只是整洁,没有必要)?
  • 我有 numpy 1.8dev 但我的工作是旧版本...

标签: numpy binning


【解决方案1】:

您可以使用更高维度的数组视图并沿额外维度取平均值:

In [12]: a = np.arange(36).reshape(6, 6)

In [13]: a
Out[13]: 
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]])

In [14]: a_view = a.reshape(3, 2, 3, 2)

In [15]: a_view.mean(axis=3).mean(axis=1)
Out[15]: 
array([[  3.5,   5.5,   7.5],
       [ 15.5,  17.5,  19.5],
       [ 27.5,  29.5,  31.5]])

一般来说,如果您想要(rows, cols) 数组的形状为(a, b) 的箱子,则您的整形应该是.reshape(rows // a, a, cols // b, b)。另请注意,.mean 的顺序很重要,例如a_view.mean(axis=1).mean(axis=3) 会报错,因为a_view.mean(axis=1) 只有三个维度,虽然a_view.mean(axis=1).mean(axis=2) 可以正常工作,但它会让人更难理解发生了什么。

照原样,上述代码仅在您可以在数组中容纳整数个 bin 时才有效,即如果 a 除以 rows 和 b 除以 cols。有一些方法可以处理其他情况,但你必须定义你想要的行为。

【讨论】:

  • 在 numpy 1.7 上。你可以把它挤成.mean(axis=(1,3))!
  • 我不知道这种重塑是可能的,太棒了!不幸的是,平均值是有序的,因此如何获得 ex 的平均值。在你的例子中一个 2,2 的子矩阵(我的意思是角 0,1,6,7 等......)?
  • @user1187727 我不认为我理解你的问题,但[[0, 1], [6, 7]] 的平均值是[0, 0] 的a_view.mean(axis=3).mean(axis=1) 项。
  • 我认为@user1187727 与重构数组(使用reshape(3, 2, 3, 2))不是 2x2 子矩阵数组这一事实混淆了,尽管结果无论如何都是正确的。
【解决方案2】:

见the SciPy Cookbook on rebinning,它提供了这个sn-p:

def rebin(a, *args):
    '''rebin ndarray data into a smaller ndarray of the same rank whose dimensions
    are factors of the original dimensions. eg. An array with 6 columns and 4 rows
    can be reduced to have 6,3,2 or 1 columns and 4,2 or 1 rows.
    example usages:
    >>> a=rand(6,4); b=rebin(a,3,2)
    >>> a=rand(6); b=rebin(a,2)
    '''
    shape = a.shape
    lenShape = len(shape)
    factor = asarray(shape)/asarray(args)
    evList = ['a.reshape('] + \
             ['args[%d],factor[%d],'%(i,i) for i in range(lenShape)] + \
             [')'] + ['.sum(%d)'%(i+1) for i in range(lenShape)] + \
             ['/factor[%d]'%i for i in range(lenShape)]
    print ''.join(evList)
    return eval(''.join(evList))

【讨论】:

    【解决方案3】:

    我假设您只想知道如何构建一个性能良好的函数并使用数组执行某些操作,就像您的示例中的 numpy.reshape 一样。因此,如果性能真的很重要并且您已经在使用 numpy,那么您可以为此编写自己的 C 代码,就像 numpy 一样。例如,arange 的实现完全用 C 语言实现。几乎所有与性能有关的 numpy 都用 C 语言实现。

    但是,在这样做之前,您应该尝试在 python 中实现代码,看看性能是否足够好。尝试使 python 代码尽可能高效。如果它仍然不能满足您的性能需求,请使用 C 方式。

    您可以在docs 中了解相关内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多