将256x256x256 numpy阵列调整为64x64x64 numpy阵列。我试图实现4的窗口大小来平均元素

2024-09-29 21:59:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个稀疏的3D NumPy数组(256x256x256),我想使用移动窗口平均值将其调整为64x64x64。解决这个问题最干净的方法是什么?我应该考虑一个4x4x4的三维平均窗口来解决这个问题吗?

我从一个1D窗口开始,如下所示,但如何有效地扩展到2D或3D

def avgWindow(arr, size):
    return (arr[(n-1):] + arr[:-(n-1)])/float(size)

Tags: 方法numpysizereturndef数组float平均值
3条回答

如果要将数据分类为更粗略的分辨率,请尝试分别沿每个维度使用np.reshapenp.mean进行分类:

A = np.array([.....])
s = A.shape  # (256, 256, 256)
B = A.copy()  # be sure to save original data

# reshape last dimension into new dim and bin-size (int div for index & shape)
B = B.reshape(s[0], s[1], s[2] // 4, 4)
B = np.mean(B, axis=-1)  # computes average along last dim
B.shape # (256, 256, 64)
... # repeat for other 2 dimensions.

这应该是合理的快速,因为您正在使用numpys内部向量化

加:

我不是稀疏矩阵方面的专家,但是如果它真的是SPAR,那么研究一下scipy.sparse可能会有用

您可以使用scipy.signal.convolve计算移动平均值,并跳过中间元素:

import numpy as np
from scipy.signal import convolve

old_shape = 256
a = np.arange(old_shape**3).reshape(old_shape, old_shape, old_shape)
new_shape = 64 # should be an integer divider of old shape
ksize = old_shape // new_shape
kernel = np.ones((ksize, ksize, ksize)) / (ksize**3)
res = convolve(a, kernel, 'valid')[::ksize,::ksize,::ksize]

只在大小为(4,4,4)的非重叠子矩阵上寻找卷积。下面是您的操作方法(可能是最快、占用内存最少的,因为它共享内存,并且不会对任何不必要的子数组进行额外计算):

from skimage.util.shape import view_as_windows
kernel = np.ones((4,4,4))
sub_matrices = view_as_windows(arr, kernel.shape, kernel.shape)
#Do convolution on extracted non-overlapping sub-matrices of shape (4,4,4)
output = np.einsum('ijk,mnlijk->mnl',kernel,sub_matrices)

如果您不希望将输出放大到内核中的点总和,只需将output除以kernel.size(即output/=kernel.size

例如:

arr=np.ones((256,256,256))

output.shape:

(64, 64, 64)

相关问题 更多 >

    热门问题