在Numpy或类似物中通过平均缩小3D矩阵

时间:2016-05-30 19:00:48

标签: numpy matrix scipy

是否有一种简单的方法可以通过平均 Numpy Scipy 中的特定大小的块,甚至使用NetC D <来减小3D矩阵的大小/ em> F工具或类似的东西?我曾经使用strides写了一个2D,但是一个随时可用的功能会有很多帮助。

修改

我喜欢输入和输出的示例:

Input's shape: (500, 500, 100)

Calling the function: downsize(input, 10, 10, 10, func)

Output's shape: (50, 50, 10)其中每个单元格的值是连续10x10x10子矩阵上func的结果。

或者,代码可以获得所需的矩阵大小作为输入而不是子矩阵的大小并将其计算出来。

由于

2 个答案:

答案 0 :(得分:3)

这是一种使用整形将每个轴切割成两个轴的方法,从而创建六个轴,然后对三个原始轴中的每个轴在第二个切片轴上执行合并平均,以获得块状平均值 -

def blockwise_average_3D(A,S):    
    # A is the 3D input array
    # S is the blocksize on which averaging is to be performed

    m,n,r = np.array(A.shape)//S
    return A.reshape(m,S[0],n,S[1],r,S[2]).mean((1,3,5))

样品运行 -

In [107]: A = np.random.randint(0,255,(500,500,100)) # 3D Input array
     ...: S = (10,10,10)                             # Blocksize
     ...: 

In [108]: out = blockwise_average_3D(A,S)

In [109]: out[0,0,0]
Out[109]: 124.242

In [110]: A[:10,:10,:10].mean()
Out[110]: 124.242

In [111]: out[0,1,0]
Out[111]: 129.89400000000001

In [112]: A[:10,10:20,:10].mean()
Out[112]: 129.89400000000001

答案 1 :(得分:0)

我最终将我的2D版本扩展为3D,显然它可以工作。在这里,万一其他人也需要它。

import numpy as np
from numpy.lib.stride_tricks import as_strided

# 3D version of my block view function
def block_view(arr, block_size):
    shape   = tuple(_shape / _bsize for _shape, _bsize in zip(arr.shape, block_size)) + block_size
    strides = tuple(_bsize * _stride for _bsize, _stride in zip(block_size, arr.strides)) + arr.strides

    return as_strided(arr, shape=shape, strides=strides)

def aggregate(arr, block_size):
    blocks = block_view(arr, block_size)
    dimension_offset = len(arr.shape)
    block_dimensions = range(dimension_offset, dimension_offset + len(block_size))
    for dim in block_dimensions:
        blocks = np.mean(blocks, axis=dim, keepdims=True)

    blocks = blocks[:, :, :, 0, 0, 0]
    return blocks

我试图让它适用于任何N维矩阵,但唯一的限制是blocks = blocks[:, :, :, 0, 0, 0]行。