Python:按比例缩放/扩展二维数组
有一些数字的2D数组
是某些数值处理的结果,这些数组的形状可以是1x1, 3x3, 5x5, ...
,它们对应着不同的分辨率。
在某个阶段,我们需要生成一个形状为nxn
的平均值,也就是一个2D数组
。如果所有的输出数组都是相同的形状,比如说都是11x11
,那解决方案就很简单了,就是:
element_wise_mean_of_all_arrays
。
但是在这个问题中,数组的形状各不相同,所以直接的方法就不适用了!
我想用kron
函数来帮助解决这个问题,但效果并不好。例如,如果一个数组的形状是17x17
,我们该如何把它变成21x21
呢?对于其他形状的数组,比如1x1
、3x3
等,如何构建一个固定形状的数组,比如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 矩阵的平均值,或者用一些插值函数。