Как "масштабировать" массив numpy? - PullRequest
24 голосов
/ 23 сентября 2011

Я хотел бы масштабировать массив формы (h, w) с коэффициентом n, в результате чего получился массив формы (h * n, w * n) с.

Скажите, чтоУ меня есть массив 2x2:

array([[1, 1],
       [0, 1]])

Я хотел бы масштабировать массив до 4x4:

array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 1, 1],
       [0, 0, 1, 1]])

То есть значение каждой ячейки в исходном массиве копируется в4 соответствующие ячейки в результирующем массиве.Предполагая произвольный размер массива и коэффициент масштабирования, какой самый эффективный способ сделать это?

Ответы [ 4 ]

47 голосов
/ 23 сентября 2011

Вы должны использовать продукт Kronecker , numpy.kron :

Вычисляет произведение Кронекера, составной массив из блоков второго массива, масштабированный по первому

import numpy as np
a = np.array([[1, 1],
              [0, 1]])
n = 2
np.kron(a, np.ones((n,n)))

, который дает то, что вы хотите:

array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 0, 1, 1],
       [0, 0, 1, 1]])
14 голосов
/ 23 сентября 2011

Вы можете использовать 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]])

Я не уверен, есть ли удобный способ объединить две операции в одну.

7 голосов
/ 19 марта 2017

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)
6 голосов
/ 22 марта 2015

Для эффективного масштабирования я использую следующий подход. Работает в 5 раз быстрее repeat и в 10 раз быстрее 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)

Теперь эта функция будет делать шкалу:

def scale(A, B, slices):        # fill A with B through slices
    for s in slices: A[s] = B

Или то же самое просто в одной функции:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...