首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >通过对numpy 2d数组进行平均或重新入库来调整大小

通过对numpy 2d数组进行平均或重新入库来调整大小
EN

Stack Overflow用户
提问于 2011-11-11 13:58:38
回答 4查看 31.4K关注 0票数 35

我正在尝试用python重新实现一个IDL函数:

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

其通过平均将2d阵列的大小缩小整数倍。

例如:

代码语言:javascript
复制
>>> 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),取相关样本的平均值,预期输出将为:

代码语言:javascript
复制
>>> 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维数组,然后在正确的切片上取平均值,但无法计算出算法。你有什么建议吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-11 14:53:37

下面是一个基于the answer you've linked的示例(为了清晰起见):

代码语言:javascript
复制
>>> 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]])

作为函数:

代码语言:javascript
复制
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)
票数 40
EN

Stack Overflow用户

发布于 2015-03-14 05:13:36

J.F. Sebastian对2D分箱有一个很好的答案。这是他的"rebin“函数的一个版本,适用于N维:

代码语言:javascript
复制
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
票数 15
EN

Stack Overflow用户

发布于 2016-06-20 16:35:02

这里有一种使用矩阵乘法来做你所要求的事情的方法,它不需要用新的数组维数除以旧的数组维数。

首先,我们生成一个行压缩器矩阵和一个列压缩器矩阵(我相信有一种更干净的方法来做这件事,甚至可能只使用numpy操作):

代码语言:javascript
复制
def get_row_compressor(old_dimension, new_dimension):
    dim_compressor = np.zeros((new_dimension, old_dimension))
    bin_size = float(old_dimension) / new_dimension
    next_bin_break = bin_size
    which_row = 0
    which_column = 0
    while which_row < dim_compressor.shape[0] and which_column < dim_compressor.shape[1]:
        if round(next_bin_break - which_column, 10) >= 1:
            dim_compressor[which_row, which_column] = 1
            which_column += 1
        elif next_bin_break == which_column:

            which_row += 1
            next_bin_break += bin_size
        else:
            partial_credit = next_bin_break - which_column
            dim_compressor[which_row, which_column] = partial_credit
            which_row += 1
            dim_compressor[which_row, which_column] = 1 - partial_credit
            which_column += 1
            next_bin_break += bin_size
    dim_compressor /= bin_size
    return dim_compressor


def get_column_compressor(old_dimension, new_dimension):
    return get_row_compressor(old_dimension, new_dimension).transpose()

..。例如,get_row_compressor(5, 3)为您提供了:

代码语言:javascript
复制
[[ 0.6  0.4  0.   0.   0. ]
 [ 0.   0.2  0.6  0.2  0. ]
 [ 0.   0.   0.   0.4  0.6]]

get_column_compressor(3, 2)为您提供了:

代码语言:javascript
复制
[[ 0.66666667  0.        ]
 [ 0.33333333  0.33333333]
 [ 0.          0.66666667]]

然后简单地与行压缩器进行预乘,并与列压缩器进行后乘,以获得压缩矩阵:

代码语言:javascript
复制
def compress_and_average(array, new_shape):
    # Note: new shape should be smaller in both dimensions than old shape
    return np.mat(get_row_compressor(array.shape[0], new_shape[0])) * \
           np.mat(array) * \
           np.mat(get_column_compressor(array.shape[1], new_shape[1]))

使用这种技术,

代码语言:javascript
复制
compress_and_average(np.array([[50, 7, 2, 0, 1],
                               [0, 0, 2, 8, 4],
                               [4, 1, 1, 0, 0]]), (2, 3))

收益率:

代码语言:javascript
复制
[[ 21.86666667   2.66666667   2.26666667]
 [  1.86666667   1.46666667   1.86666667]]
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8090229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档