這樣向量化的東西是棘手的,因爲擺脫環比n
元素,你必須構造的陣列,因此對於大的投入,你很可能得到一個更壞的性能比Python的循環。不過,這是可以做到:
mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt((x[:, None] - x)**2 + (y[:, None] - y)**2)
perp = np.abs(z[:, None] - z)
hist, _, _ = np.histogram2d(para[mask], perp[mask], bins=[rpbins, pibins])
的mask
是爲了避免計數兩次,每次距離。我還將對角線偏移設置爲1
,以避免在直方圖中包括每個點與其自身的距離0
。但是如果你沒有索引para
和perp
,你會得到與你的代碼完全相同的結果。
有了這個樣本數據:
items = 100
rpbins, pibins = np.linspace(0, 1, 3), np.linspace(0, 1, 3)
x = np.random.rand(items)
y = np.random.rand(items)
z = np.random.rand(items)
我得到這個我hist
和你out
:
>>> hist
array([[ 1795., 651.],
[ 1632., 740.]])
>>> out
array([[ 3690., 1302.],
[ 3264., 1480.]])
和out[i, j] = 2 * hist[i, j]
除了i = j = 0
,因爲0
距離各項目到哪裏out[0, 0] = 2 * hist[0, 0] + items
本身。
編輯試圖tcaswell的評論後,以下:
items = 1000
rpbins, pibins = np.linspace(0, 1, 3), np.linspace(0, 1, 3)
x, y, z = np.random.rand(3, items)
def hist1(x, y, z, rpbins, pibins) :
mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt((x[:, None] - x)**2 + (y[:, None] - y)**2)
perp = np.abs(z[:, None] - z)
hist, _, _ = np.histogram2d(para[mask], perp[mask], bins=[rpbins, pibins])
return hist
def hist2(x, y, z, rpbins, pibins) :
mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt((x[:, None] - x)[mask]**2 + (y[:, None] - y)[mask]**2)
perp = np.abs((z[:, None] - z)[mask])
hist, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
return hist
def hist3(x, y, z, rpbins, pibins) :
mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt(((x[:, None] - x)**2 + (y[:, None] - y)**2)[mask])
perp = np.abs((z[:, None] - z)[mask])
hist, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
return hist
In [10]: %timeit -n1 -r10 hist1(x, y, z, rpbins, pibins)
1 loops, best of 10: 289 ms per loop
In [11]: %timeit -n1 -r10 hist2(x, y, z, rpbins, pibins)
1 loops, best of 10: 294 ms per loop
In [12]: %timeit -n1 -r10 hist3(x, y, z, rpbins, pibins)
1 loops, best of 10: 278 ms per loop
看來,大部分的時間都花在實例化新的陣列,而不是做實際的計算,因此,儘管有一些效率刮關閉,真的不多。
我主要是因爲先生E的評論[這裏](http://stackoverflow.com/questions/8299891/vectorization-of-this-numpy-double-loop):「我用matlab標記了這個因爲可能有一個簡單的解決方案,matlab用戶知道,更多的時候,在Numpy中沒有相應的功能「對不起,我沒有想到。 – Alex 2013-02-19 07:15:21
標籤上足夠公平。 – tacaswell 2013-02-19 07:17:02