如何"缩放"一个numpy数组?

Dav*_*Eyk 24 python arrays scaling numpy

我想将形状(h,w)的数组缩放n倍,得到一个形状的数组(h*n,w*n),其中.

假设我有一个2x2阵列:

array([[1, 1],
       [0, 1]])
Run Code Online (Sandbox Code Playgroud)

我想将数组缩放为4x4:

array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 1, 1],
       [0, 0, 1, 1]])
Run Code Online (Sandbox Code Playgroud)

也就是说,原始数组中每个单元格的值被复制到结果数组中的4个相应单元格中.假设任意数组大小和缩放因子,最有效的方法是什么?

And*_*ffe 47

您应该使用克罗内克产品,numpy.kron:

计算Kronecker产品,这是一个由第一个数组缩放的第二个数组的块组成的复合数组

import numpy as np
a = np.array([[1, 1],
              [0, 1]])
n = 2
np.kron(a, np.ones((n,n)))
Run Code Online (Sandbox Code Playgroud)

给出你想要的东西:

array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 1, 1],
       [0, 0, 1, 1]])
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,与此处的“a.repeat(n, 1).repeat(n, 0)”方法相比,“np.kron()”在大数组上相当慢。对于更复杂的子模式来说是可以的。 (2认同)

NPE*_*NPE 14

你可以使用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]])
Run Code Online (Sandbox Code Playgroud)

我不确定是否有一种巧妙的方法将两种操作合二为一.


Mik*_*l V 7

为了有效地扩展我使用以下方法.工作速度比快5倍,速度快repeat10倍kron.首先,初始化目标数组,以就地填充缩放数组.并预定义切片以赢得几个周期:

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)
Run Code Online (Sandbox Code Playgroud)

现在这个函数将执行扩展:

def scale(A, B, slices):        # fill A with B through slices
    for s in slices: A[s] = B
Run Code Online (Sandbox Code Playgroud)

或者只是在一个函数中同样的事情:

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
Run Code Online (Sandbox Code Playgroud)


Mar*_*oma 7

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)
Run Code Online (Sandbox Code Playgroud)