изменение размера с усреднением или ребином массива numpy 2d

Я пытаюсь повторно реализовать в 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] ) и т. Д.

Я считаю, что мне нужно преобразовать форму в четырехмерный массив, а затем взять среднее значение на правильном срезе, но не смог понять алгоритм. Вы можете подсказать?

26
задан Andrea Zonca 11 November 2011 в 05:58
поделиться

1 ответ

J.F. У Себастьяна отличный ответ для 2D биннинга. Вот версия его функции «rebin», которая работает для N измерений:

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
12
ответ дан 28 November 2019 в 07:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: