无论如何,你应该以不同的方式做事.不幸的是,速度快得多的cKDTree没有必要的功能,但即使是其他KDTree也应该给你一个巨大的速度提升(并且更加优雅地解决它)
from scipy.spatial import KDTree
from itertools import chain
tree = KDTree(circles)
# unfortunatly only a list of lists, because there may be a different amount
# also the point itself is included every time.
connections = tree.query_ball_tree(tree, 2*r)
# if all you want is a list of lists of what connects with what
# connections is already what you need. The rest creates a connectivity matrix:
repeats = [len(l) for l in connections]
x_point = np.arange(len(circles)).repeat(repeats)
y_point = np.fromiter(chain(*connections), dtype=np.intp)
# or construct a sparse matrix here instead, scipy.sparse has some graph tools
# maybe it even has a better thing to do this.
connected = np.zeros((len(circles),) * 2, dtype=bool)
connected[x_point, y_point] = True
虽然它不巧妙地使用cKDTree,但这仍然可以节省你的O(N ^ 2)复杂度…当然如果len(圆圈)很小,那没关系,但是你可以只使用广播,(或者distance_matrix from scipy.spatial):
distances = np.sqrt(((circles[:,None,:] - circles)**2).sum(-1))
connected = distances < (2 * r)
# if you need the list of lists/arrays here you can do:
connections = [np.flatnonzero(c) for c in connected]
但请注意,第二种方法是一个记忆饥饿的怪物,只有圆圈很小才有好处.