Numpyアレイでブロックワイズ操作を行うための便利なユーティリティはありますか?Numpyのブロックワイズ操作
私は、行列をブロックに分割し、各ブロックがその合計、平均または他の関数に置き換えられる行列を返す、スピン再正規化のような操作を考えています。
Numpyアレイでブロックワイズ操作を行うための便利なユーティリティはありますか?Numpyのブロックワイズ操作
私は、行列をブロックに分割し、各ブロックがその合計、平均または他の関数に置き換えられる行列を返す、スピン再正規化のような操作を考えています。
superbatfish's blockwise_view
を探している可能性があります。これはnp.lib.stride_tricks.as_strided
を使用して配列のビューを作成し、配列の「ブロック」を独自の軸に配置します。
は、たとえば、次のような2次元アレイがあると、
In [97]: arr = np.arange(24).reshape(6, 4)
In [98]: arr.shape
Out[98]: (6, 4)
In [99]: arr
Out[99]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
とシェイプの4つのブロックに「それをチョップ」したい(3、2)。今、あなたはそれを再構築できた一つのブロックからのすべての値が最後の軸である
In [34]: blocked = blockwise_view(arr, (3, 2)); blocked
Out[34]:
array([[[[ 0, 1],
[ 4, 5],
[ 8, 9]],
[[ 2, 3],
[ 6, 7],
[10, 11]]],
[[[12, 13],
[16, 17],
[20, 21]],
[[14, 15],
[18, 19],
[22, 23]]]])
In [37]: blocked.shape
Out[37]: (2, 2, 3, 2)
:
あなたは(4、3 2)形状の4D配列に変換するblockwise_view
を使用することができます
In [41]: reshaped = blocked.reshape(-1, 3*2); reshaped
Out[41]:
array([[ 0, 1, 4, 5, 8, 9],
[ 2, 3, 6, 7, 10, 11],
[12, 13, 16, 17, 20, 21],
[14, 15, 18, 19, 22, 23]])
今、あなたは、その軸に沿って合計し、またはその平均を取るか、各ブロックの要素に他のいくつかの機能を適用することができます。
In [103]: reshaped.sum(axis=-1)
Out[103]: array([ 27, 39, 99, 111])
In [104]: reshaped.mean(axis=-1)
Out[104]: array([ 4.5, 6.5, 16.5, 18.5])
my first answerとは異なり、whic hは2D配列にのみ適用でき、 blockwise_view
は任意のN次元配列に適用できます。 2 N次元配列を返します。最初のN軸はブロックをインデックスします。
ブロック単位操作をスライドさせるため、あなたが列にImplement Matlab's im2col_sliding 'sliding' in python
そのグループから各ブロックの実装を借りることができ、それによってブロックワイズ操作がaxis = 0
に沿ってそのように動作するベクトル化ソリューションのすべてNumPy ufuncs
を受け入れるように簡単になります。等のブロック状sum
、average
、std
を計算する
def im2col_sliding(A,BLKSZ):
# Parameters
M,N = A.shape
col_extent = N - BLKSZ[1] + 1
row_extent = M - BLKSZ[0] + 1
# Get Starting block indices
start_idx = np.arange(BLKSZ[0])[:,None]*N + np.arange(BLKSZ[1])
# Get offsetted indices across the height and width of input array
offset_idx = np.arange(row_extent)[:,None]*N + np.arange(col_extent)
# Get all actual indices & index into input array for final output
return np.take (A,start_idx.ravel()[:,None] + offset_idx.ravel())
サンプル実行 - - ここで関数を作成するようにスライディングブロックを定義するための正式な方法だ
In [6]: arr # Sample array
Out[6]:
array([[6, 5, 0, 6, 0],
[7, 4, 2, 3, 6],
[6, 3, 3, 8, 1],
[5, 5, 1, 1, 8]])
In [7]: im2col_sliding(arr,[2,3]) # Blockwise array with blocksize : (2,3)
Out[7]:
array([[6, 5, 0, 7, 4, 2, 6, 3, 3],
[5, 0, 6, 4, 2, 3, 3, 3, 8],
[0, 6, 0, 2, 3, 6, 3, 8, 1],
[7, 4, 2, 6, 3, 3, 5, 5, 1],
[4, 2, 3, 3, 3, 8, 5, 1, 1],
[2, 3, 6, 3, 8, 1, 1, 1, 8]])
In [8]: np.sum(im2col_sliding(arr,[2,3]),axis=0) # Perform blockwise summation
Out[8]: array([24, 20, 17, 25, 23, 23, 23, 21, 22])
In [9]: np.mean(im2col_sliding(arr,[2,3]),axis=0) # Perform blockwise averaging
Out[9]:
array([ 4. , 3.33333333, 2.83333333, 4.16666667, 3.83333333,
3.83333333, 3.83333333, 3.5 , 3.66666667])
In [10]: np.std(im2col_sliding(arr,[2,3]),axis=0) # Blockwise std. deviation
Out[10]:
array([ 2.38047614, 1.97202659, 2.47767812, 1.77169097, 1.95078332,
2.40947205, 1.67497927, 2.43241992, 3.14466038])
Scikitにview_as_windows' 'もありますScikit-learnで-imageと 'extract_patches'を実行します。 –