13

(厳密には 2 次元の) numpy 配列内の重複しない連続した部分行列を調べる必要があるアルゴリズムを実装しています。たとえば、12 x 12 の場合

>>> a = np.random.randint(20, size=(12, 12)); a
array([[ 4,  0, 12, 14,  3,  8, 14, 12, 11, 18,  6,  6],
       [15, 13,  2, 18, 15, 15, 16,  2,  9, 16,  6,  4],
       [18, 18,  3,  8,  1, 15, 14, 13, 13, 13,  7,  0],
       [ 1,  9,  3,  6,  0,  4,  3, 15,  0,  9, 11, 12],
       [ 5, 15,  5,  6,  4,  4, 18, 13, 10, 17, 11,  8],
       [13, 17,  8, 15, 17, 12,  7,  1, 13, 15,  0, 18],
       [ 2,  1, 11, 12,  3, 16, 11,  9, 10, 15,  4, 16],
       [19, 11, 10,  7, 10, 19,  7, 13, 11,  9, 17,  8],
       [14, 14, 17,  0,  0,  0, 11,  1, 10, 14,  2,  7],
       [ 6, 15,  6,  7, 15, 19,  2,  4,  6, 16,  0,  3],
       [ 5, 10,  7,  5,  0,  8,  5,  8,  9, 14,  4,  3],
       [17,  2,  0,  3, 15, 10, 14,  1,  0,  7, 16,  2]])

3x3 サブマトリックスを見て、最初の 3x3 サブマトリックスを左上隅に配置したいと思います。

>>> a[0:3, 0:3]
array([[ 4,  0, 12],
       [15, 13,  2],
       [18, 18,  3]])

などによって与えられる次のアロングa[0:3, 3:6]。各行または列の最後のそのような一連のインデックスが配列の末尾からはみ出すかどうかは問題ではありません。存在するスライス内の部分を単に与えるという numpy の動作で十分です。

任意のサイズの行列と部分行列に対して、これらのスライス インデックスをプログラムで生成する方法が必要です。私は現在これを持っています:

size = 3
x_max = a.shape[0]
xcoords = range(0, x_max, size)
xcoords = zip(xcoords, xcoords[1:])

同様に、 を生成するy_coordsため、一連のインデックスは で与えられitertools.product(xcoords, ycoords)ます。

私の質問は次のとおりです。これを行うためのより直接的な方法はありnumpy.mgridますか?

4

3 に答える 3

8

インデックスを取得する

size x size特定のブロックを取得する簡単な方法は次のとおりです。

base = np.arange(size) # Just the base set of indexes
row = 1                # Which block you want
col = 0                
block = a[base[:, np.newaxis] + row * size, base + col * size]

xcoords必要に応じて、次のようなマトリックスを構築できます。

y, x = np.mgrid[0:a.shape[0]/size, 0:a.shape[1]/size]
y_coords = y[..., np.newaxis] * size + base
x_coords = x[..., np.newaxis] * size + base

次に、次のようなブロックにアクセスできます。

block = a[y_coords[row, col][:, np.newaxis], x_coords[row, col]]

ブロックを直接取得する

ブロックだけを取得したい場合 (ブロック エントリのインデックスではなく)、次のようにnp.split(2 回)使用します。

blocks = map(lambda x : np.split(x, a.shape[1]/size, 1), # Split the columns
                        np.split(a, a.shape[0]/size, 0)) # Split the rows

size x size次に、ブロックの 2D リストがあります。

>>> blocks[0][0]
array([[ 4,  0, 12],
       [15, 13,  2],
       [18, 18,  3]])

>>> blocks[1][0]
array([[ 1,  9,  3],
       [ 5, 15,  5],
       [13, 17,  8]])

次に、これを numpy 配列にして、上記と同じインデックス スタイルを使用できます。

>>> blocks = np.array(blocks)
>>> blocks.shape
(4, 4, 3, 3)
于 2013-05-23T13:21:13.417 に答える