Python:按比例缩放/扩展二维数组

3 投票
1 回答
2273 浏览
提问于 2025-04-17 10:57

有一些数字的2D数组是某些数值处理的结果,这些数组的形状可以是1x1, 3x3, 5x5, ...,它们对应着不同的分辨率。

在某个阶段,我们需要生成一个形状为nxn的平均值,也就是一个2D数组。如果所有的输出数组都是相同的形状,比如说都是11x11,那解决方案就很简单了,就是:

element_wise_mean_of_all_arrays

但是在这个问题中,数组的形状各不相同,所以直接的方法就不适用了!

我想用kron函数来帮助解决这个问题,但效果并不好。例如,如果一个数组的形状是17x17,我们该如何把它变成21x21呢?对于其他形状的数组,比如1x13x3等,如何构建一个固定形状的数组,比如21x21

还有一种情况是,数组的形状比目标形状要小或大,比如说一个31x31的数组需要缩小到21x21

你可以把这个问题想象成一个很常见的任务,就是对图像进行缩小或扩展。

那么在Python中,使用numpy、scipy等库,有哪些高效的方法可以处理这些2D数组呢?

更新:这里有一个稍微优化过的版本,来自下面被接受的答案:


def resize(X,shape=None):
    if shape==None:
        return X
    m,n = shape
    Y = np.zeros((m,n),dtype=type(X[0,0]))
    k = len(X)
    p,q = k/m,k/n
    for i in xrange(m):
        Y[i,:] = X[i*p,np.int_(np.arange(n)*q)]
    return Y

这个方法效果很好,不过大家觉得在效率上它是最佳选择吗?如果不是,有什么改进的建议吗?


# Expanding ---------------------------------

>>> X = np.array([[1,2,3],[4,5,6],[7,8,9]])
[[1 2 3]
 [4 5 6]
 [7 8 9]]

>>> resize(X,[7,11])
[[1 1 1 1 2 2 2 2 3 3 3]
 [1 1 1 1 2 2 2 2 3 3 3]
 [1 1 1 1 2 2 2 2 3 3 3]
 [4 4 4 4 5 5 5 5 6 6 6]
 [4 4 4 4 5 5 5 5 6 6 6]
 [7 7 7 7 8 8 8 8 9 9 9]
 [7 7 7 7 8 8 8 8 9 9 9]]

# Shrinking ---------------------------------

>>> X = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [13 14 15 16]]

>>> resize(X,(2,2))
[[ 1  3]
 [ 9 11]]

最后说明:上面的代码可以很容易地转换成Fortran,以获得更高的性能。

1 个回答

2

我不太确定你具体想要做什么,但如果我没理解错,最简单的方法可能是:

wanted_size = 21
a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
b = numpy.zeros((wanted_size, wanted_size))

for i in range(wanted_size):
    for j in range(wanted_size):
        idx1 = i * len(a) / wanted_size
        idx2 = j * len(a) / wanted_size
        b[i][j] = a[idx1][idx2]

你可以把 b[i][j] = a[idx1][idx2] 这行代码换成一个自定义的函数,比如计算一个以 a[idx1][idx2] 为中心的 3x3 矩阵的平均值,或者用一些插值函数。

撰写回答