2013-05-09 303 views
2

假設我有一個包含行向量的矩陣nxm。我想要一個距離矩陣nxn來表示每個向量相互之間的距離。我如何在Python中使用Numpy進行操作。我知道Scipy做到了,但我想要我的手。我已經寫了一個餘弦相似函數cos_dist(a,b)其中a和b兩個不同的向量。現在我需要一個調用者函數,它可以有效地處理每對項目。我會怎麼做?計算給定行向量矩陣的距離矩陣

+0

如果SciPy的這樣做,爲什麼不看看相關功能的源代碼?它可能僅僅取決於numpy。 – fgb 2013-05-09 20:26:34

+0

未安裝,我不是SUDO – erogol 2013-05-09 20:37:27

+0

您是否知道相關功能的名稱?你可以只是谷歌的源代碼。 – fgb 2013-05-09 20:47:43

回答

2

你爲什麼不檢查SciPy的的spatial.distance.pdist(),其計算觀測之間成對的距離在n維空間,並有大量的距離函數可供選擇?

由於您沒有安裝scipy並且想要使用numpy對其進行編碼,所以我建議您研究its source code,該文檔鏈接在其文檔頁面的左上角。

+0

謝謝你的努力,但沒有足夠的,因爲有很多包裝 – erogol 2013-05-09 21:21:26

+0

np。我希望這至少能讓你開始朝正確的方向發展。 – fgb 2013-05-09 21:26:54

2

下面的代碼顯示了兩個選項,可以完成您的任務。一次在數組上循環兩次,並使用Python函數計算cos_dist。第二種方法使用向量化方法,broadcasting以更快的速度獲得相同的結果x1000。

from __future__ import division 
import numpy as np 

def cos_dist(a, b): 
    mod_a = np.sqrt(a.dot(a)) 
    mod_b = np.sqrt(b.dot(b)) 
    return a.dot(b)/mod_a/mod_b 

a = np.random.rand(100, 4) 

# Slow option 
def slow_dist(a): 
    items = a.shape[0] 
    out_slow = np.ones((items,items)) 
    for j in xrange(items): 
     for k in xrange(j+1, items): 
      out_slow[j, k] = cos_dist(a[j], a[k]) 
      out_slow[k, j] = out_slow[j, k] 
    return out_slow 

# Faster option 
from numpy.core.umath_tests import inner1d 
def fast_dist(a): 
    mod_a = np.sqrt(inner1d(a ,a)) 
    norm_a = a/mod_a[:, None] 
    out_fast = inner1d(norm_a[:, None, :], 
         norm_a[None, :, :]) 
    return out_fast 

這裏是計時:

In [2]: %timeit slow_dist(a) 
10 loops, best of 3: 67.6 ms per loop 

In [3]: %timeit fast_dist(a) 
10000 loops, best of 3: 60.5 us per loop 

In [4]: np.allclose(slow_dist(a), fast_dist(a)) 
Out[4]: True