配列があるとします。
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
そしてx
、(行/列のインデックスではなく)その行列のサイズを定義することによって、常に中央に配置される小さな配列のコピーを取得したいと思います。
たとえば、これから2x2配列が必要な場合は、次のようになります。
[[5 6]
[9 10]]
私の目的のために、私の初期配列はより大きく(4096x4096)、サイズ(128x128)、(256x256)、(512x512)、(1024x1024)、(2048x2048)の中央の正方形配列のコピーを取りたいと思います。
また、元の配列を保持したいので、必ずしも元の行/列をスライスする必要はありません。代わりに、元のコピーのみをトリミングして、新しい変数に保存する必要があります。
私は次のようないくつかの変数を定義することを考えていました:(2x2の場合):
rows_to_keep = [1,2]
cols_to_keep = [1,2]
その後、
x[np.ix_(rows_to_keep, columns_to_keep)]
しかし、これがrows_to_keep
最大2048の数値のリストである場合、これは実用的ではなくなります。たとえば、元の4096x4096から128x128の正方形をコピーするには、1984年の行/列から2112までのインデックスのリストを作成できます。
size_to_keep = 128
indices = np.linspace(0, size_to_keep, size_to_keep, endpoint=False)
rows_to_keep = [(4096/2)-(size_to_keep/2) + i for i in indices]
cols_to_keep = [(4096/2)-(size_to_keep/2) + i for i in indices]
copy_array = x[np.ix_(rows_to_keep, columns_to_keep)]
しかし、これも厄介/非現実的になります。私はこれを行うためのよりパイソン的な方法があることを望んでいましたか?前もって感謝します
すべてのインデックスは連続しているため、適切なを使用できますslice
。明らかに、極値の計算を避けることはできませんが、それだけです。
これは次の形式をとることができます(任意の整数値で機能することを確認するためのコードを含むsize
):
def get_center(arr, size):
mask = tuple(
slice(int(dim / 2 - size / 2), int(dim / 2 + size / 2))
if 0 < size < dim else slice(None)
for dim in arr.shape)
return arr[mask].copy()
これは次のように簡単に使用できます。
import numpy as np
dim = 4
x = np.arange(dim * dim).reshape((dim, dim))
y = get_center(x, 2)
# [[ 5, 6],
# [ 9, 10]]
期待どおりに動作しますが、それほど多くのメモリを消費することはありません。
もちろん、極値を調整して、奇妙なケースを好きなように処理することもできます(質問では実際には定義されていません)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加