I would like to scale an array of shape (h, w) by a factor of n, resulting in an array of shape (h*n, w*n), with the.
我想把一个形状的数组(h, w)按n的一个因子进行缩放,结果是一个形状数组(h*n, w*n)。
Say that I have a 2x2 array:
假设我有一个2x2数组:
array([[1, 1],
[0, 1]])
I would like to scale the array to become 4x4:
我想把这个数组扩展成4x4:
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 1]])
That is, the value of each cell in the original array is copied into 4 corresponding cells in the resulting array. Assuming arbitrary array size and scaling factor, what's the most efficient way to do this?
也就是说,原始数组中的每个单元的值被复制到结果数组中的4个相应的单元格中。假设任意数组大小和比例因子,最有效的方法是什么?
4 个解决方案
#1
37
You should use the Kronecker product, numpy.kron:
您应该使用Kronecker产品,numpy.kron:
Computes the Kronecker product, a composite array made of blocks of the second array scaled by the first
计算Kronecker产品,这是一个由第一个数组的块组成的复合数组。
import numpy as np
a = np.array([[1, 1],
[0, 1]])
n = 2
np.kron(a, np.ones((n,n)))
which gives what you want:
这就是你想要的:
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 1]])
#2
14
You could use repeat
:
您可以使用重复:
In [6]: a.repeat(2,axis=0).repeat(2,axis=1)
Out[6]:
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 1]])
I am not sure if there's a neat way to combine the two operations into one.
我不确定是否有一个巧妙的方法将这两个操作合并为一个。
#3
5
To scale effectively I use following approach. Works 5 times faster than repeat
and 10 times faster that kron
. First, initialise target array, to fill scaled array in-place. And predefine slices to win few cycles:
为了有效地扩展,我使用以下方法。工作速度是重复的5倍,速度是kron的10倍。首先,初始化目标数组,以填充按比例排列的数组。并预先定义切片以赢得几个周期:
K = 2 # scale factor
a_x = numpy.zeros((h * K, w *K), dtype = a.dtype) # upscaled array
Y = a_x.shape[0]
X = a_x.shape[1]
myslices = []
for y in range(0, K) :
for x in range(0, K) :
s = slice(y,Y,K), slice(x,X,K)
myslices.append(s)
Now this function will do the scale:
现在这个函数会做缩放:
def scale(A, B, slices): # fill A with B through slices
for s in slices: A[s] = B
Or the same thing simply in one function:
或者是同一个函数
def scale(A, B, k): # fill A with B scaled by k
Y = A.shape[0]
X = A.shape[1]
for y in range(0, k):
for x in range(0, k):
A[y:Y:k, x:X:k] = B
#4
3
scipy.misc.imresize
can scale images. It can be used to scale numpy arrays, too:
scipy.misc。imresize可以扩展图像。它也可以用于扩展numpy数组:
#!/usr/bin/env python
import numpy as np
import scipy.misc
def scale_array(x, new_size):
min_el = np.min(x)
max_el = np.max(x)
y = scipy.misc.imresize(x, new_size, mode='L', interp='nearest')
y = y / 255 * (max_el - min_el) + min_el
return y
x = np.array([[1, 1],
[0, 1]])
n = 2
new_size = n * np.array(x.shape)
y = scale_array(x, new_size)
print(y)
#1
37
You should use the Kronecker product, numpy.kron:
您应该使用Kronecker产品,numpy.kron:
Computes the Kronecker product, a composite array made of blocks of the second array scaled by the first
计算Kronecker产品,这是一个由第一个数组的块组成的复合数组。
import numpy as np
a = np.array([[1, 1],
[0, 1]])
n = 2
np.kron(a, np.ones((n,n)))
which gives what you want:
这就是你想要的:
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 1]])
#2
14
You could use repeat
:
您可以使用重复:
In [6]: a.repeat(2,axis=0).repeat(2,axis=1)
Out[6]:
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 1, 1]])
I am not sure if there's a neat way to combine the two operations into one.
我不确定是否有一个巧妙的方法将这两个操作合并为一个。
#3
5
To scale effectively I use following approach. Works 5 times faster than repeat
and 10 times faster that kron
. First, initialise target array, to fill scaled array in-place. And predefine slices to win few cycles:
为了有效地扩展,我使用以下方法。工作速度是重复的5倍,速度是kron的10倍。首先,初始化目标数组,以填充按比例排列的数组。并预先定义切片以赢得几个周期:
K = 2 # scale factor
a_x = numpy.zeros((h * K, w *K), dtype = a.dtype) # upscaled array
Y = a_x.shape[0]
X = a_x.shape[1]
myslices = []
for y in range(0, K) :
for x in range(0, K) :
s = slice(y,Y,K), slice(x,X,K)
myslices.append(s)
Now this function will do the scale:
现在这个函数会做缩放:
def scale(A, B, slices): # fill A with B through slices
for s in slices: A[s] = B
Or the same thing simply in one function:
或者是同一个函数
def scale(A, B, k): # fill A with B scaled by k
Y = A.shape[0]
X = A.shape[1]
for y in range(0, k):
for x in range(0, k):
A[y:Y:k, x:X:k] = B
#4
3
scipy.misc.imresize
can scale images. It can be used to scale numpy arrays, too:
scipy.misc。imresize可以扩展图像。它也可以用于扩展numpy数组:
#!/usr/bin/env python
import numpy as np
import scipy.misc
def scale_array(x, new_size):
min_el = np.min(x)
max_el = np.max(x)
y = scipy.misc.imresize(x, new_size, mode='L', interp='nearest')
y = y / 255 * (max_el - min_el) + min_el
return y
x = np.array([[1, 1],
[0, 1]])
n = 2
new_size = n * np.array(x.shape)
y = scale_array(x, new_size)
print(y)