web-dev-qa-db-ja.com

派手な配列を「スケーリング」する方法は?

形状(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つのセルにコピーされます。任意の配列サイズとスケーリング係数を想定して、これを行う最も効率的な方法は何ですか?

26
David Eyk

Kronecker productnumpy.kron を使用する必要があります。

1つ目でスケーリングされた2つ目の配列のブロックで構成される複合配列であるクロネッカー積を計算します

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]])
48
Andrew Jaffe

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]])

2つの操作を1つにまとめるきちんとした方法があるかどうかはわかりません。

14
NPE

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)
8
Martin Thoma

効果的にスケーリングするには、次のアプローチを使用します。 repeatの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)

この関数はスケールを実行します:

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

または、同じことを単純に1つの関数で行います。

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
7
Mikhail V