繰り返しパターンの行列を作る方法。
いわゆる、Matlabでいうところのrepmatをやりたい時
方法は2つある。
- numpy.matlib.repmatを使う
- numpy.tileを使う
1. numpy.matlib.repmatを使う方法
numpy.matlib.repmat(a, m, n)
In [1]: import numpy as np
In [2]: import numpy.matlib
In [3]: np.matlib.repmat((1,2,3),1,5)
Out[3]: array([[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]])
In [4]: A = np.diag((100,200,300))
In [5]: print A
[[100 0 0]
[ 0 200 0]
[ 0 0 300]]
In [6]: np.matlib.repmat(A,2,2)
Out[6]:
array([[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300],
[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300]])
In [7]: np.matlib.repmat(A,1,2)
Out[7]:
array([[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300]])
In [8]: np.matlib.repmat(A,2,1)
Out[8]:
array([[100, 0, 0],
[ 0, 200, 0],
[ 0, 0, 300],
[100, 0, 0],
[ 0, 200, 0],
[ 0, 0, 300]])
2. numpy.tileを使う方法
numpy.tile(a, reps)
In [9]: np.tile((1,2,3),(1,5))
Out[9]: array([[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]])
In [10]: np.tile(A,(2,2))
Out[10]:
array([[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300],
[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300]])
In [11]: np.tile(A,(1,2))
Out[11]:
array([[100, 0, 0, 100, 0, 0],
[ 0, 200, 0, 0, 200, 0],
[ 0, 0, 300, 0, 0, 300]])
In [12]: np.tile(A,(2,1))
Out[12]:
array([[100, 0, 0],
[ 0, 200, 0],
[ 0, 0, 300],
[100, 0, 0],
[ 0, 200, 0],
[ 0, 0, 300]])
repmatを使うと例えば二次元配列の偶数位置だけ残して、残りは0にしたいときなどに使える。
In [27]: X = np.arange(100).reshape(10,10)
In [28]: Y = np.matlib.repmat(np.array([[1,0],[0,0]]),5,5)
In [29]: print X
[[ 0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]]
In [30]: print Y
[[1 0 1 0 1 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 1 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 1 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 1 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0]
[1 0 1 0 1 0 1 0 1 0]
[0 0 0 0 0 0 0 0 0 0]]
In [31]: Z = X * Y
In [32]: print Z
[[ 0 0 2 0 4 0 6 0 8 0]
[ 0 0 0 0 0 0 0 0 0 0]
[20 0 22 0 24 0 26 0 28 0]
[ 0 0 0 0 0 0 0 0 0 0]
[40 0 42 0 44 0 46 0 48 0]
[ 0 0 0 0 0 0 0 0 0 0]
[60 0 62 0 64 0 66 0 68 0]
[ 0 0 0 0 0 0 0 0 0 0]
[80 0 82 0 84 0 86 0 88 0]
[ 0 0 0 0 0 0 0 0 0 0]]
カラー画像の場合は三次元データなので下記のようになる。
ipython
In [1]: from skimage import data
In [2]: from skimage import io
In [3]: import numpy as np
In [4]: sz = 48
In [5]: image = data.lena()
In [6]: patch1 = image[250:250+sz,250:250+sz,:]
In [7]: patch1.shape
Out[7]: (48, 48, 3)
In [8]: mask = np.tile(np.array([[[1],[0]],[[0],[0]]],dtype=np.uint8),(sz/2,sz/2,3))
In [9]: mask.shape
Out[9]: (48, 48, 3)
In [10]: print mask
[[[1 1 1]
[0 0 0]
[1 1 1]
...,
[0 0 0]
[1 1 1]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]
...,
[0 0 0]
[0 0 0]
[0 0 0]]]
In [11]: patch2 = patch1 * mask
In [12]: patch12 = np.hstack((patch1,patch2))