扩展/缩放numpy数组

10

我有以下数组:

import numpy as np
a = np.array([[2, 3, 5],
              [4, 6, 7],
              [1, 5, 7]])

我想将它扩展为这个数组:

b = [[2 2 2 3 3 3 5 5 5]
     [2 2 2 3 3 3 5 5 5]
     [2 2 2 3 3 3 5 5 5]
     [4 4 4 6 6 6 7 7 7]
     [4 4 4 6 6 6 7 7 7]
     [4 4 4 6 6 6 7 7 7]
     [1 1 1 5 5 5 7 7 7]
     [1 1 1 5 5 5 7 7 7]
     [1 1 1 5 5 5 7 7 7]]

所以我正在使用以下命令:

import scipy.ndimage
b = scipy.ndimage.interpolation.zoom(a, 3, order=0)
根据这个问题和答案 Resampling a numpy array representing an image

然而,我得到的是:

b = [[2 2 3 3 3 3 5 5 5]
     [2 2 3 3 3 3 5 5 5]
     [4 4 6 6 6 6 7 7 7]
     [4 4 6 6 6 6 7 7 7]
     [4 4 6 6 6 6 7 7 7]
     [4 4 6 6 6 6 7 7 7]
     [1 1 5 5 5 5 7 7 7]
     [1 1 5 5 5 5 7 7 7]
     [1 1 5 5 5 5 7 7 7]]

我希望扩展恰好为3,或者是任何缩放因子,但目前对于数组的每个元素都不同。

有没有直接的方法来做到这一点?还是我应该手动编写一些代码来实现?

3个回答

14

可能有点晚了,但为了完整起见:Numpy Kron完美地完成了这项工作。

>>> import numpy as np
>>> a = np.array([[2,3,5], [4,6,7], [1,5,7]])
>>> np.kron(a, np.ones((3,3)))
array([[ 2.,  2.,  2.,  3.,  3.,  3.,  5.,  5.,  5.],
       [ 2.,  2.,  2.,  3.,  3.,  3.,  5.,  5.,  5.],
       [ 2.,  2.,  2.,  3.,  3.,  3.,  5.,  5.,  5.],
       [ 4.,  4.,  4.,  6.,  6.,  6.,  7.,  7.,  7.],
       [ 4.,  4.,  4.,  6.,  6.,  6.,  7.,  7.,  7.],
       [ 4.,  4.,  4.,  6.,  6.,  6.,  7.,  7.,  7.],
       [ 1.,  1.,  1.,  5.,  5.,  5.,  7.,  7.,  7.],
       [ 1.,  1.,  1.,  5.,  5.,  5.,  7.,  7.,  7.],
       [ 1.,  1.,  1.,  5.,  5.,  5.,  7.,  7.,  7.]])

2
永不迟到!公正地说,这个答案比@MSeifert的答案更完整、更易于实现。那个答案对于一个2D数组完美地工作,但是我发现在我的3D数组上应用它时遇到了困难。 你的答案另一个好处是,你可以分别决定每个维度的扩展值,在你不想将数组在所有方向上都扩展相同值的情况下,这一点非常重要。 目前我肯定会说:这就是答案。 - philippos
1
你能具体说明或举个例子,你所说的“我发现在我的三维数组上应用它有困难”是什么意思吗? - thilo_dual
2
你需要使用类似于 np.kron(a, np.ones((4,4,1))) 这样的东西,可选地加上 .astype(np.uint8) 作为后缀,因为 kron 自动返回浮点数数组。 - chenjesu

1
我不知道在NumPy或SciPy中是否有完全符合您要求的功能,但是您可以轻松地自行创建一个:
from __future__ import division
import numpy as np

def zoom(a, factor):
    a = np.asarray(a)
    slices = [slice(0, old, 1/factor) for old in a.shape]
    idxs = (np.mgrid[slices]).astype('i')
    return a[tuple(idxs)]

它会给出预期的结果:

>>> a = [[2,3,5], [4,6,7], [1,5,7]]

>>> zoom(a,3)
array([[2, 2, 2, 3, 3, 3, 5, 5, 5],
       [2, 2, 2, 3, 3, 3, 5, 5, 5],
       [2, 2, 2, 3, 3, 3, 5, 5, 5],
       [4, 4, 4, 6, 6, 6, 7, 7, 7],
       [4, 4, 4, 6, 6, 6, 7, 7, 7],
       [4, 4, 4, 6, 6, 6, 7, 7, 7],
       [1, 1, 1, 5, 5, 5, 7, 7, 7],
       [1, 1, 1, 5, 5, 5, 7, 7, 7],
       [1, 1, 1, 5, 5, 5, 7, 7, 7]])

我还没有对所有因素和形状进行测试,也许由于浮点精度问题(切片中的步骤参数),这种方法可能会遇到麻烦。

1
这正是我想要的!谢谢。我还不熟悉 slicenp.ngrid,所以根据我的当前知识,我会用完全不同的方式解决它,但是你的函数恰好做到了我想要的。我测试了非方形形状、浮点数组,它完美地工作了。 - philippos

1
这是我的方法,使用简单的numpy函数。它返回与输入相同的数据类型。
import numpy as np

def zoom(a, factor):
    sx, sy = (factor * dim for dim in a.shape)
    X, Y = np.ogrid[0:sx, 0:sy]
    return a[X//factor, Y//factor]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接