2016-11-13 98 views
1

減少或擴展在下面的代碼我們計算所有對給定的點之間的矢量的大小。爲加快與NumPy此操作,我們可以使用廣播廣播與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] 
+0

'pair_vectors'是10x10x3。我不明白10x10x6會包含什麼。 – hpaulj

+1

這個'norm'是:'np.sqrt(np.sum(pair_vectors ** 2,axis = 2))'。它彌補了所有的差異;在尺寸3的尺寸上求和並採用sqrt。 – hpaulj

+1

'nditer'有點像'zip'列表。它協調多個數組的迭代。在處理廣播時,它也超越了'zip'。但是你已經在'c'代碼('cython')中使用它來獲得任何真正的速度改進。 – hpaulj

回答

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討論,所以看看有太多!

+0

pdist在c中使用循環,並且不允許將週期性邊界放入acount中。 – liberias

+0

@liberias對不起,我們在這裏討論的是什麼邊界?你能詳細說明一下嗎? – Divakar

+0

說你要計算的差異向量,然後應用週期性邊界對他們來說,這意味着,如果有任何的差別向量座標的超過一些最大箱尺寸(邊界),那麼你需要或者減少或增加包裝盒的大小。這可以通過廣播輕鬆完成,然後使用標誌功能和調節。我認爲使用pdist是不可能的,這使得它對我來說毫無用處。但無論如何,pdist只是一個用C語言編譯的雙循環,然後用Python運行,它並不能解決使用NumPy的問題。 – liberias