
[英]Find nearest neighbors of a numpy array in list of numpy arrays using euclidian distance
[英]Creating a list of nearest neighbors using numpy array
基于截止距离,我想创建一个点列表,这些点是给定点的邻居。 我被困在如何将点的ID添加到numpy数组中。
我在numpy数组中读取了“坐标”,如下所示:
ID x y z
1. 1 1 0.000000 3.078000 0.554000
2. 2 0.000000 3.078000 2.170000
3. 3 2.666000 1.539000 0.554000
4. 4 2.666000 1.539000 2.170000
5. 5 1.774000 0.000000 3.324000
6. 6 2.712000 0.000000 7.207000
等等...
我想要这样的输出列表
ID neighbor1 neighbor2 ....neighbor5
1. 1 4 5 6 8
2. 2 1 4 6 n/a
3. 3 5 1 n/a 2
4. etc.
因此每个位置(1、2、3、4 ...等等)最多可以有5个邻居,如果少于5个,我想在其中放置n / a。 到目前为止,我有以下代码。
#neighborlist
flist = glob.glob(filename)
for f in flist:
load = np.loadtxt(f, usecols=(2,3,4))
coordinate=np.array(load)
s = (len(coordinate),6)
Nlist = np.zeros(s)
rcut = 2.5 #cutoff distance for neighbors
for f in flist:
load = np.loadtxt(f, usecols=(2,3,4))
coordinate=np.array(load)
for i in range(len(coordinate)):
idx = [i,]
for j in range(len(coordinate)):
if np.linalg.norm(coordinate[i]-coordinate[j]) < rcut and np.linalg.norm(coordinate[i]-coordinate[j]) > 0.1:
idx.append(j)
else:
idx = idx
while len(idx)<6:
idx.append('n/a')
print idx
Nlist[i,:]=idx
print Nlist
为此,我得到:
ValueError:无法将字符串转换为浮点数:n / a
因为我已经将Nlist
数组的大小固定为(len(data),6)
所以当邻居小于5(第一个元素是点本身)时Nlist[i,:]=idx
它无法复制Nlist[i,:]=idx
。 在这种情况下,有没有办法动态声明Nlist
或使其大小可变? 我知道这是一个棘手的问题,但必须解决这个问题。 提前致谢。
可以这样做:
import numpy as np
from collections import defaultdict
coordinate = np.array([[0. , 3.078, 0.554],
[ 0. , 3.078, 2.17 ],
[ 2.666, 1.539, 0.554],
[ 2.666, 1.539, 2.17 ],
[ 1.774, 0. , 3.324],
[ 2.712, 0. , 7.207]])
rcut = 2.5
neighbors = defaultdict(list)
for ID1, ID2 in itertools.permutations(range(len(coordinate)), 2):
if np.linalg.norm(coordinate[ID1]-coordinate[ID2]) < rcut:
neighbors[ID1].append(ID2)
else:
neighbors[ID1].append('n/a')
for ID in neighbors:
print ID, neighbors[ID]
输出:
0 [1, 'n/a', 'n/a', 'n/a', 'n/a']
1 [0, 'n/a', 'n/a', 'n/a', 'n/a']
2 ['n/a', 'n/a', 3, 'n/a', 'n/a']
3 ['n/a', 'n/a', 2, 4, 'n/a']
4 ['n/a', 'n/a', 'n/a', 3, 'n/a']
5 ['n/a', 'n/a', 'n/a', 'n/a', 'n/a']
请注意,我为输出使用了词典,我认为这比列表更有意义。 由于您的代码不会读取ID,而是将行号作为ID,所以我也这样做。 随着numpy从0开始编号,ID从0开始。
另请注意,您的代码只会评估文件列表中的最后一个文件,因为您会覆盖读取的每个文件的坐标数组。
为什么要在输出中存储“ n / a”,而不是简单地具有不同ID的长度可变的列表?
还要注意,我建议的代码不是很有效。 您可以使用像单元格列表这样的算法来加快处理速度。
如果您想高效地找到邻居,您可能还对scipy.spatial模块感兴趣,该模块可以做到这一点:
from scipy import spatial
kdtree = sp.spatial.KDTree(coordinate)
kdtree.query_pairs(rcut)
输出:
{(0, 1), (2, 3), (3, 4)}
这将为您提供所有距离小于rcut的点对。 这是构建所需输出列表所需的基本信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.