是否有一种简单的方法可以通过平均 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
的结果。
或者,代码可以获得所需的矩阵大小作为输入而不是子矩阵的大小并将其计算出来。
由于
答案 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]
行。