ndimage.zoom
这可能是最好的方法,zoom method 正是为此类任务而设计的。
from scipy.ndimage import zoom
new_array = zoom(array, (0.5, 0.5, 2))
按指定因子更改每个维度的大小。如果数组的原始形状是(40, 50, 60),那么新的形状将是(20, 25, 120)。
signal.resample_poly
SciPy 有一个large set of methods 用于信号处理。这里最相关的是decimate 和resample_poly。我在下面使用后者
from scipy.signal import resample_poly
factors = [(1, 2), (1, 2), (2, 1)]
for k in range(3):
array = resample_poly(array, factors[k][0], factors[k][1], axis=k)
因子(必须是整数)是上采样和下采样的。那就是:
- (1, 2) 表示大小除以 2
- (2, 1) 表示大小乘以 2
- (2, 3) 表示先增加 2,然后再减少 3,因此大小乘以 2/3
可能的缺点:该过程在每个维度上独立发生,因此可能无法像 ndimage 方法那样考虑空间结构。
RegularGridInterpolator
这更需要动手操作,但也更费力,而且没有过滤的好处:直接下采样。我们必须为插值器制作一个网格,在每个方向上使用原始步长。插值器创建后,需要在新的网格上进行评估;它的调用方法采用另一种网格格式,用mgrid 准备。
values = np.random.randint(0, 256, size=(40, 50, 60)).astype(np.uint8) # example
steps = [0.5, 0.5, 2.0] # original step sizes
x, y, z = [steps[k] * np.arange(array.shape[k]) for k in range(3)] # original grid
f = RegularGridInterpolator((x, y, z), values) # interpolator
dx, dy, dz = 1.0, 1.0, 1.0 # new step sizes
new_grid = np.mgrid[0:x[-1]:dx, 0:y[-1]:dy, 0:z[-1]:dz] # new grid
new_grid = np.moveaxis(new_grid, (0, 1, 2, 3), (3, 0, 1, 2)) # reorder axes for evaluation
new_values = f(new_grid)
缺点:例如,当一个维度减少 2 时,它实际上会每隔一个值下降一次,这就是简单的下采样。理想情况下,在这种情况下应该平均相邻值。在信号处理方面,decimation 中的低通滤波先于下采样。