2016-03-30 8 views
0

私は値の2次元行列を持っています。各行はデータポイントです。私のテスト・ポイントのような単一1D numpyの配列である場合多次元データでnumpyを使用してユークリッド距離の外側ループをベクトル化する

data = np.array(
    [[2, 2, 3], 
    [4, 2, 4], 
    [1, 1, 4]]) 

今:

test = np.array([2,3,3]) 

私はすべての3つのデータポイントにテストポイントの相対的な距離を計算するnp.sqrt(np.sum((test-data)**2,axis=1))のような単純な何かを行うことができます。テストポイントの2Dアレイをテストするためにそれ自身である場合

しかし、上記機能せず、私のような何かを使用して:に対して設定私のテストの各点を計算するために

test = np.array([[2,3,3],[4,1,2]])  
for i in range(len(test)): 
    print np.sqrt(np.sum((test[i]-data)**2,axis=1)) 

>>> [ 1.   2.44948974 2.44948974] 
    [ 2.44948974 2.23606798 3.60555128] 

をデータセット内のすべての点。この全体の操作をベクトル化して、対応する距離の行列を外部のFORループなしで返すようにする必要があるようです。

(注:この特定の例はユークリッド距離についてですが、I同じタイプの操作で、あるマトリックスのすべての要素を別のマトリックスの個々の要素で操作したいと思っているので、Numpyを使用してこの性質の問題を設定する一般的な方法があることを願っています。

+0

これが動作しているようですが、私は大規模のメモリ使用量が心配です各テストポイントをN回複製する必要があるように見えるデータセット。ここで、Nは開始するデータポイントの数です。したがって、1000のデータポイントがある場合は、2つの値をテストするために2000ポイントの行列を作成する必要があります。 'print np.reshape(np.sqrt(np.sum(np.repeat(test、len(data)、axis = 0)、(len(test)* len(data)、Xdims) )、 (2、len(data)))。T' –

+2

[scipyのcdist](http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.spatial.distance.cdist.html)を使用してください: 'from scipy.spatial.distance輸入cdist; out = cdist(テスト、データ) '。それは超効率的です。 – Divakar

答えて

-2

あなたは、リストの内包表記を使用することができます。

result = np.array([np.sqrt(np.sum((t - data)**2, axis=1)) for t in test]) 
+0

私の理解は、理解はちょうど素晴らしいFORループに過ぎないということです。私の希望はnumpyの速度を利用し、Pythonのループを避けることです。 –

1

何についてnp.meshgrid

import numpy as np 

data = np.array(
    [[2, 2, 3], 
    [4, 2, 4], 
    [1, 1, 4]]) 


test = np.array([[2,3,3], 
       [4,1,2]]) 


d = np.arange(0,3) 
t = np.arange(0,2) 
d, t = np.meshgrid(d, t) 

# print test[t] 
# print data[d] 
print np.sqrt(np.sum((test[t]-data[d])**2,axis=2)) 

出力:それをする

[[ 1.   2.44948974 2.44948974] 
[ 2.44948974 2.23606798 3.60555128]] 
+0

Divakarのポストを見て、私は 'scipy'' cdist'と行くつもりです。 – roadrunner66

2

が使用broadcasting

[ 1.   2.44948974 2.44948974] 
[ 2.44948974 2.23606798 3.60555128] 

いくつかの説明のための

from numpy.linalg import norm 
norm(data-test[:,None],axis=2) 

。その後

ens1 = np.array(
    [[2, 2, 3], 
    [4, 2, 4], 
    [1, 1, 4], 
    [2, 4, 5]]) 


ens2 = np.array([[2,3,3], 
       [4,1,2]]) 


In [16]: ens1.shape 
Out[16]: (4, 3) 

In [17]: ens2.shape 
Out[17]: (2, 3) 

In [21]: ens2[:,None].shape 
Out[21]: (2, 1, 3) 

を新たな次元を追加するには、異なる形状でexempleための4つの2点を理解することが容易です。今、私たちは、2X4 = 8つの減算することができます:

In [22]: (ens1-ens2[:,None]).shape 
Out[22]: (2, 4, 3)  

をし、8つの距離のために、最後の軸に沿ってノルムを取る:

In [23]: norm(ens1-ens2[:,None],axis=2) 
Out[23]: 
array([[ 1.  , 2.44948974, 2.44948974, 2.23606798], 
     [ 2.44948974, 2.23606798, 3.60555128, 4.69041576]])