我写了一个Python脚本来计算3D空间中的两个点之间的距离,同时考虑周期性边界条件。 问题是,我需要很多很多个这样的计算,计算速度很慢。 这里是我的功能。
def PBCdist(coord1,coord2,UC):
dx = coord1[0] - coord2[0]
if (abs(dx) > UC[0]*0.5):
dx = UC[0] - dx
dy = coord1[1] - coord2[1]
if (abs(dy) > UC[1]*0.5):
dy = UC[1] - dy
dz = coord1[2] - coord2[2]
if (abs(dz) > UC[2]*0.5):
dz = UC[2] - dz
dist = np.sqrt(dx**2 + dy**2 + dz**2)
return dist
那么我所说的功能等等
for i, coord2 in enumerate(coordlist):
if (PBCdist(coord1,coord2,UC) < radius):
do something with i
最近我读到我可以极大地利用列表理解提高性能。 对于非PBC情况下工作,而不是为PBC情况
coord_indices = [i for i, y in enumerate([np.sqrt(np.sum((coord2-coord1)**2)) for coord2 in coordlist]) if y < radius]
for i in coord_indices:
do something
是否有某种方式来做到这对中国人民银行情况相同呢? 是否有将工作的替代更好?
你应该写你的distance()
函数中,你可以vectorise在5711点的循环方式。 以下实现接受点作为任一的阵列x0
或x1
参数:
def distance(x0, x1, dimensions):
delta = numpy.abs(x0 - x1)
delta = numpy.where(delta > 0.5 * dimensions, delta - dimensions, delta)
return numpy.sqrt((delta ** 2).sum(axis=-1))
例:
>>> dimensions = numpy.array([3.0, 4.0, 5.0])
>>> points = numpy.array([[2.7, 1.5, 4.3], [1.2, 0.3, 4.2]])
>>> distance(points, [1.5, 2.0, 2.5], dimensions)
array([ 2.22036033, 2.42280829])
其结果是作为第二个参数传递给该点之间的距离的阵列distance()
和中的每个点points
。
import numpy as np
bounds = np.array([10, 10, 10])
a = np.array([[0, 3, 9], [1, 1, 1]])
b = np.array([[2, 9, 1], [5, 6, 7]])
min_dists = np.min(np.dstack(((a - b) % bounds, (b - a) % bounds)), axis = 2)
dists = np.sqrt(np.sum(min_dists ** 2, axis = 1))
这里a
和b
是向量的名单要计算之间的距离和bounds
是空间(所以这里所有三个维度从0到10,然后包裹)的边界。 它可以计算之间的距离a[0]
和b[0]
a[1]
和b[1]
等等。
我敢肯定,numpy的专家可以做的更好,但是这可能会是一个数量级比你在做什么更快,因为大部分的工作在C.现在完成
看看伊恩Ozsvalds 高性能蟒蛇教程 。 它包含了大量的建议,在那里你可以去下一个。
包含:
- 矢量
- 用Cython
- pypy
- numexpr
- pycuda
- multiprocesing
- 平行蟒蛇
我发现, meshgrid
是产生距离非常有用的。 例如:
import numpy as np
row_diff, col_diff = np.meshgrid(range(7), range(8))
radius_squared = (row_diff - x_coord)**2 + (col_diff - y_coord)**2
我现在有一个数组( radius_squared
)其中每一条目指定从阵列位置的距离的平方[x_coord, y_coord]
以环阵,我可以做到以下几点:
row_diff, col_diff = np.meshgrid(range(7), range(8))
row_diff = np.abs(row_diff - x_coord)
row_circ_idx = np.where(row_diff > row_diff.shape[1] / 2)
row_diff[row_circ_idx] = (row_diff[row_circ_idx] -
2 * (row_circ_idx + x_coord) +
row_diff.shape[1])
row_diff = np.abs(row_diff)
col_diff = np.abs(col_diff - y_coord)
col_circ_idx = np.where(col_diff > col_diff.shape[0] / 2)
col_diff[row_circ_idx] = (row_diff[col_circ_idx] -
2 * (col_circ_idx + y_coord) +
col_diff.shape[0])
col_diff = np.abs(row_diff)
circular_radius_squared = (row_diff - x_coord)**2 + (col_diff - y_coord)**2
我现在都用矢量数学览的排列距离。
文章来源: Optimizing Python distance calculation while accounting for periodic boundary conditions