LoginSignup
25
23

More than 5 years have passed since last update.

[Python]繰り返しパターンの行列を作る方法(repmat/tile)

Last updated at Posted at 2016-01-04

繰り返しパターンの行列を作る方法。
いわゆる、Matlabでいうところのrepmatをやりたい時

方法は2つある。
1. numpy.matlib.repmatを使う
2. 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))

20160104_6.png

25
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
23