最も「numpythonic」の方法は、broadcastingを使用することです。これは、距離行列を計算するための素早く簡単な方法です。その場合、絶対値のargmin
を取ることができます。 dmat
の
array1 = np.random.rand(4004001)
array2 = np.random.rand(1000)
# Calculate distance matrix (on truncated array1 for memory reasons)
dmat = array1[:400400] - array2[:,None]
# Take the abs of the distance matrix and work out the argmin along the last axis
ix = np.abs(dmat).argmin(axis=1)
は形状:
(1000, 400400)
ix
やコンテンツの形状:
(1000,)
array([237473, 166831, 72369, 11663, 22998, 85179, 231702, 322752, ...])
は、あなたが一度にこの操作を行う場合は、それはメモリ空腹だし、実際にはしません指定した配列のサイズのために私の8GBマシンで作業します。そのため、array1
のサイズを小さくしました。
メモリの制約内で動作させるには、アレイの1つをチャンクにスライスし、順番に(または並列に)各チャンクにブロードキャストを適用します。この場合、array2
を10チャンクにスライスしました。
# Define number of chunks and calculate chunk size
n_chunks = 10
chunk_len = array2.size // n_chunks
# Preallocate output array
out = np.zeros(1000)
for i in range(n_chunks):
s = slice(i*chunk_len, (i+1)*chunk_len)
out[s] = np.abs(array1 - array2[s, None]).argmin(axis=1)
両方の配列を最初に並べ替えます。その後、大きな配列をステップ実行し、小さな配列の現在の最も近い要素へのインデックスを保持します。必要に応じてインデックスをインクリメントします。これをスピードアップするものがあれば、私はひどく驚くことはありません。 –
[numpy配列で最も近い値を見つける]の複製があります。(0120-18751) –