numpy の ndarray のサブクラスを実装して__getitem__
おり、配列の平坦化された表現からアイテムをフェッチするように変更する必要があります。問題は__getitem__
、整数インデックスまたは多次元スライスで呼び出すことができることです。
フラット化された配列で多次元スライスをインデックスのリスト(または単次元スライス)に変換する方法を知っている人はいますか?
多次元スライスをフラット スライスに変換できない場合があります。次に例を示します。
>>> a = np.arange(16).reshape(4, 4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> a[::3, 1::2]
array([[ 1, 3],
[13, 15]])
[ 1, 3, 13, 15]
また、start:stop:step
表記法で部分配列にアクセスすることはできません。しかし、次のようにして、多次元インデックスからフラット インデックスのリストを作成できます。
>>> row_idx = np.arange(4)[::3]
>>> col_idx = np.arange(4)[1::2]
>>> row_idx = np.repeat(row_idx, 2)
>>> col_idx = np.tile(col_idx, 2)
>>> np.ravel_multi_index((row_idx, col_idx), dims=(4,4))
array([ 1, 3, 13, 15], dtype=int64)
より一般的な設定では、各次元のインデックスの配列を取得したら、すべてのインデックス配列のデカルト積を作成する必要があるため、itertools.product
おそらくこれが適切な方法です。例えば:
>>> indices = [np.array([0, 4, 8]), np.array([1,7]), np.array([3, 5, 9])]
>>> indices = zip(*itertools.product(*indices))
>>> indices
[(0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8),
(1, 1, 1, 7, 7, 7, 1, 1, 1, 7, 7, 7, 1, 1, 1, 7, 7, 7),
(3, 5, 9, 3, 5, 9, 3, 5, 9, 3, 5, 9, 3, 5, 9, 3, 5, 9)]
>>> np.ravel_multi_index(indices, dims=(10, 11, 12))
array([ 15, 17, 21, 87, 89, 93, 543, 545, 549, 615, 617,
621, 1071, 1073, 1077, 1143, 1145, 1149], dtype=int64)