简体   繁体   English

计算numpy数组的某些条目之间的欧式距离

[英]Calculating the Euclidean distance between SOME entries of numpy array

I am a bit new to numpy and I am trying to calculate the pairwaise distance between some of the elements of a numpy array. 我对numpy有点陌生,我正在尝试计算numpy数组的某些元素之间的结对距离。

I have a numpy nx 3 array with n 3D cartesian coordinates (x,y,z) representing particles in a grid. 我有一个numpy nx 3数组,其中n个3D笛卡尔坐标(x,y,z)表示网格中的粒子。 Some of these particles move as the program runs and I need to keep track of the distances of the ones that move. 其中一些粒子会随着程序运行而移动,我需要跟踪移动对象的距离。 I hold a list of integers with the index of the particles that have moved. 我持有一个整数列表,其中包含已移动粒子的索引。

I am aware of pdist but this calculates the distance between every pair of particles, which would be inefficient as only some of them have moved. 我知道pdist,但这会计算每对粒子之间的距离,这将是低效率的,因为只有其中一些粒子移动了。 Ideally, for example, if only 1,2 have moved then I would only calculate the distance of 1 with 2...N and 2 with 3...N 理想情况下,例如,如果仅移动了1,2,则我将仅计算1与2 ... N的距离和2与3 ... N的距离

What would be the most efficient way of doing this? 最有效的方法是什么? Right now I have a double loop which doesn't seem ideal... 现在我有一个似乎不太理想的双循环...

for i in np.nditer(particles_moved): particles = particles[particles!=i] for j in np.nditer(particles): distance(xyz,i, j)

Thanks 谢谢

I believe this is what you want (create new axis and use broadcasting for full vectorization): 我相信这就是您想要的(创建新轴并使用广播进行完全矢量化):

import numpy as np

particles = np.arange(12).reshape((-1,3))
moved = np.array([0,2])
np.linalg.norm(particles[moved][:,None,:]-particles[None,:,:], axis=-1)

array([[  0.        ,   5.19615242,  10.39230485,  15.58845727],
       [ 10.39230485,   5.19615242,   0.        ,   5.19615242]])

If you wan't to use a jit compiler, here is an example using Numba 如果您不想使用jit编译器,这里是使用Numba的示例

@nb.njit(fastmath=True,parallel=True)
def distance(Paticle_coords,indices_moved):
  dist_res=np.empty((indices_moved.shape[0],Paticle_coords.shape[0]),dtype=Paticle_coords.dtype)

  for i in range(indices_moved.shape[0]):
    Koord=Paticle_coords[indices_moved[i],:]
    dist_res[i,:]=np.sqrt((Koord[0]-Paticle_coords[:,0])**2+(Koord[1]-Paticle_coords[:,1])**2+(Koord[2]-Paticle_coords[:,2])**2)

  return dist_res

Performance compared to Julien's solution 与Julien解决方案相比的性能

#Create Data
Paticle_coords=np.random.rand(10000000,3)
indices_moved=np.array([0,5,6,3,7],dtype=np.int64)

This gives on my Core i7-4771 0.15s for the Numba solution and 2.4s for Julien's solution. 这在我的Core i7-4771上为Numba解决方案提供了0.15s,为Julien解决方案提供了2.4s。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM