2

次のコードでは、指定されたポイントのすべてのペア間のベクトルの大きさを計算します。NumPy でこの操作を高速化するために、ブロードキャストを使用できます

import numpy as np
points = np.random.rand(10,3)

pair_vectors = points[:,np.newaxis,:] - points[np.newaxis,:,:]
pair_dists = np.linalg.norm(pair_vectors,axis=2).shape

または外積反復

it = np.nditer([points,points,None], flags=['external_loop'], op_axes=[[0,-1,1],[-1,0,1],None])
for a,b,c in it:
    c[...] = b - a
pair_vectors = it.operands[2]
pair_dists = np.linalg.norm(pair_vectors,axis=2)

私の質問は、ブロードキャストまたは外積反復を使用して、最後の軸にペア (拡張) の両方のポイントの座標が含まれる 10x10x6 の形式の配列を作成する方法です。また、関連する方法で、ブロードキャストまたは外積反復を直接使用してペア距離を計算することは可能ですか。つまり、最初に差分ベクトルを計算することなく (リダクション)、10x10 の形式の行列を生成します。

明確にするために、次のコードは低速ループを使用して目的の行列を作成します。

pair_coords = np.zeros(10,10,6)
pair_dists = np.zeros(10,10)
for i in range(10):
    for j in range(10):
        pair_coords[i,j,0:3] = points[i,:]
        pair_coords[i,j,3:6] = points[j,:]
        pair_dists[i,j] = np.linalg.norm(points[i,:]-points[j,:])

これは、外積反復法を使用して距離を計算する (またはペアの両方のポイントの 6 つの座標を取得してスカラーを生成する他の関数を適用する) 試みに失敗しました。

res = np.zeros((10,10))
it = np.nditer([points,points,res], flags=['reduce_ok','external_loop'], op_axes=[[0,-1,1],[-1,0,1],None])
for a,b,c in it: c[...] = np.linalg.norm(b-a)
pair_dists = it.operands[2]
4

1 に答える 1

1

ベクトル化された方法でこれらの配列を生成するアプローチは次のとおりです-

from itertools import product
from scipy.spatial.distance import pdist, squareform

N = points.shape[0]

# Get indices for selecting rows off points array and stacking them 
idx = np.array(list(product(range(N),repeat=2)))
p_coords = np.column_stack((points[idx[:,0]],points[idx[:,1]])).reshape(N,N,6)

# Get the distances for upper triangular elements. 
# Then create a symmetric one for the final dists array.
p_dists = squareform(pdist(points))

で説明されている他のベクトル化されたアプローチはほとんどないthis postので、そちらも参照してください。

于 2016-11-13T11:58:31.330 に答える