タイトルが言っていることのほとんど。私はドキュメントを読んで、しばらくの間この機能を試しましたが、この変換の物理的な兆候が何であるかを見分けることはできません。
コンピュータのメモリは直線的にアドレスされます。各メモリセルは番号に対応しています。メモリブロックは、最初の要素のメモリアドレスであるベース、およびアイテムインデックスでアドレス指定できます。たとえば、ベースアドレスが10,000であると仮定します。
item index 0 1 2 3
memory address 10,000 10,001 10,002 10,003
多次元ブロックを保存するには、それらのジオメトリを何らかの方法で線形メモリに収まるように作成する必要があります。 C
およびNumPy
では、これは行ごとに行われます。 2Dの例は次のとおりです。
| 0 1 2 3
--+------------------------
0 | 0 1 2 3
1 | 4 5 6 7
2 | 8 9 10 11
したがって、たとえば、この3行4列のブロックでは、2Dインデックス(1, 2)
は線形インデックスに対応します6
これは1 x 4 + 2
。
unravel_index
は逆を行います。線形インデックスが与えられると、対応するND
インデックスを計算します。これはブロックの次元に依存するため、これらも渡す必要があります。したがって、この例では、元の2Dインデックス(1, 2)
線形インデックスから戻る6
:
>>> np.unravel_index(6, (3, 4))
(1, 2)
注:上記では、いくつかの詳細について説明します。 1)アイテムのインデックスをメモリアドレスに変換するには、アイテムのサイズも考慮する必要があります。たとえば、整数は通常4バイトまたは8バイトです。したがって、後者の場合、アイテムi
のメモリアドレスはbase + 8 x i
。 2)。 NumPyは、提案されているよりも少し柔軟です。必要に応じて、列ごとにND
データを整理できます。メモリ内で連続していないがギャップなどを残しているデータも処理できます。
ドキュメントの例から始めます。
_>>> np.unravel_index([22, 41, 37], (7,6))
(array([3, 6, 6]), array([4, 5, 1]))
_
まず、_(7,6)
_は、インデックスを元に戻すターゲット配列の次元を指定します。第二に、_[22, 41, 37]
_はこの配列のいくつかのインデックスです配列が平坦化されている場合 7 x 6配列が平坦化されている場合、そのインデックスは次のようになります
_[ 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*]
_
これらのインデックスを元の位置に戻し、薄暗い_(7, 6)
_配列に戻すと、次のようになります。
_ [[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, *22*, 23], <- (3, 4)
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35],
[36, *37*, 38, 39, 40, *41*]]
(6, 1) (6,5)
_
_unravel_index
_関数の戻り値は、配列が平坦化されていない場合に[22、41、37]のインデックスはどうあるべきかを示しています。配列が平坦化されていない場合、これらのインデックスは[(3, 4), (6, 5), (6,1)]
になっているはずです。つまり、この関数は、平坦化された配列のインデックスを平坦化されていないバージョンに転送します。
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unravel_index.html
非常に簡単な例で説明できます。これはnp.ravel_multi_indexとnp.unravel_index
X = np.array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
X.shape = (5, 2)
すべての値がXに存在する場所を見つける
idx = np.where(X==3)
Output: idx = (array([1, 3, 3], dtype=int64), array([1, 0, 1], dtype=int64))
i.e, x = [1, 3, 3]
y = [1, 0, 1]
インデックスのx、yを返します[Xは2次元であるため]
Uが適用される場合ravel_multi_index取得したidxに対して
idx_flat = np.ravel_multi_index(idx, X.shape)
Output: idx_flat = array([3, 6, 7], dtype=int64)
idx_flat is a linear index of X where value 3 presents
上記の例から、理解できます。
結果のインデックスは、X.ravel()の直接インデックスになります。以下で確認できますx_linear
x_linear = X.ravel()
Output: x_linear = array([4, 2, 9, 3, 8, 5, 3, 3, 5, 6])
一方、nravel_indexは非常に単純で、上記の逆(np.ravel_multi_index)
idx = np.unravel_index(idx_flat , X.shape)
Output: (array([1, 3, 3], dtype=int64), array([1, 0, 1], dtype=int64))
idx = np.where(X == 3)と同じです