我想计算3维中一组点之间的所有距离矢量。所有位置都存储在一个形状数组中(numberOfPoints,3)。使用两个循环执行此操作需要大约10秒才能获得1000点。
代码是:
allDistances = np.zeros(numberOfPoints, numberOfPoints, 3)
for i in range(numberOfPoints):
for j in range(numberOfPoints):
if j>i:
allDistances[i][j] = allPoints[j] - allPoints[i]
allDistances[j][i] = -allDistances[i][j]
现在是否有任何技巧或甚至是一种方法来加速计算?不幸的是,欧几里德距离(scipy.spatial.distance.pdist())在我的情况下是不够的,因为我必须在之后检查距离向量的每个元素以获得阈值并且可能操纵它(最小图像约定)。我必须做的是:
np.where(allDistances > threshold, allDistances%threshold - threshold, allDistances)
np.where(allDistances < -threshold, allDistances%threshold, allDistances)
答案 0 :(得分:0)
我不知道numpy subtract能够以元素方式减去不同长度的数组。这使您可以轻松创建一个数组,其中包含从allPositions中的第i个位置到allPositions中所有位置的所有距离向量。请注意,allPositions具有维度(numberOfAtoms,3),而allPositions [i]因此具有维度(1,3)。 Numpy减法的工作方式如下:
allPositions[i] - allPositions = [allPositions[i] - allPositions[0],
allPositions[i] - allPositions[1],
...,
allPositions[i] - allPositions[numberOfAtoms]]
因此,你可以摆脱至少一个for循环:
for i in range(numberOfPoints):
# calculate all distance vectors from the ith atom position in allPositions
# to every atom position in allPositions
allDistancs[i] = allPositions[i] - allPositions
比较原始发布方法和此方法的速度,我发现因子为200:
import numpy as np
numberOfAtoms = 1000
allPositions = np.random.rand(numberOfAtoms, 3)
allDistances = np.zeros([numberOfAtoms, numberOfAtoms, 3])
def calcAllDis1():
for i in range(numberOfAtoms):
for j in range(numberOfAtoms):
if j>i:
allDistances[i][j] = allPositions[i] - allPositions[j]
allDistances[j][i] = -allDistances[i][j]
def calcAllDis2():
for i in range(numberOfAtoms):
allDistances[i] = allPositions[i] - allPositions
%timeit calcAllDis1()
3s per loop
%timeit calcAllDis2()
14 ms per loop
在python中有更快的方法来计算allDistances吗?