通过平均调整大小或重新合并一个 numpy 二维数组

新手上路,请多包涵

我试图在 python 中重新实现一个 IDL 函数:

http://star.pst.qub.ac.uk/idl/REBIN.html

它通过平均缩小二维数组的整数倍。

例如:

 >>> 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]])

我想通过取相关样本的平均值将其大小调整为 (2,3),预期输出为:

 >>> b = rebin(a, (2, 3))
>>> b
array([[  3.5,   5.5,  7.5],
       [ 15.5, 17.5,  19.5]])

b[0,0] = np.mean(a[:2,:2]), b[0,1] = np.mean(a[:2,2:4]) 等等。

我相信我应该重塑为一个 4 维数组,然后在正确的切片上取平均值,但无法弄清楚算法。你有什么提示吗?

原文由 Andrea Zonca 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 861
2 个回答

这是一个基于 您链接的答案 的示例(为清楚起见):

 >>> import numpy as np
>>> 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,a.shape[0]//2,3,-1)).mean(axis=3).mean(1)
array([[  3.5,   5.5,   7.5],
       [ 15.5,  17.5,  19.5]])

作为一个功能:

 def rebin(a, shape):
    sh = shape[0],a.shape[0]//shape[0],shape[1],a.shape[1]//shape[1]
    return a.reshape(sh).mean(-1).mean(1)

原文由 jfs 发布,翻译遵循 CC BY-SA 3.0 许可协议

JF Sebastian 对 2D 合并有一个很好的答案。这是他的适用于 N 维的“rebin”函数的一个版本:

 def bin_ndarray(ndarray, new_shape, operation='sum'):
    """
    Bins an ndarray in all axes based on the target shape, by summing or
        averaging.

    Number of output dimensions must match number of input dimensions and
        new axes must divide old ones.

    Example
    -------
    >>> m = np.arange(0,100,1).reshape((10,10))
    >>> n = bin_ndarray(m, new_shape=(5,5), operation='sum')
    >>> print(n)

    [[ 22  30  38  46  54]
     [102 110 118 126 134]
     [182 190 198 206 214]
     [262 270 278 286 294]
     [342 350 358 366 374]]

    """
    operation = operation.lower()
    if not operation in ['sum', 'mean']:
        raise ValueError("Operation not supported.")
    if ndarray.ndim != len(new_shape):
        raise ValueError("Shape mismatch: {} -> {}".format(ndarray.shape,
                                                           new_shape))
    compression_pairs = [(d, c//d) for d,c in zip(new_shape,
                                                  ndarray.shape)]
    flattened = [l for p in compression_pairs for l in p]
    ndarray = ndarray.reshape(flattened)
    for i in range(len(new_shape)):
        op = getattr(ndarray, operation)
        ndarray = op(-1*(i+1))
    return ndarray

原文由 derricw 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题