Python Scipy和Networkx:如何计算欧几里德距离矩阵?

Python Scipy和Networkx:如何计算欧几里德距离矩阵?,python,matrix,scipy,networkx,Python,Matrix,Scipy,Networkx,我正在使用PythonNetworkx构建一个图,我以以下节点位置为例(positions.txt): 节点ID,X,Y。我使用熊猫读取文件,并将位置设置为Networkx中的节点属性。使用for循环(无自边)中的add_edge(id1,id2,weight)方法添加节点。到目前为止,我假设默认情况下所有节点都相互连接,并且没有考虑节点的半径或距离等参数。 现在,我想使用这些节点位置计算节点之间的欧几里德半径或距离矩阵,并使用该矩阵,我想能够打印位于给定半径n内的节点的邻居,并将该文件保存为c

我正在使用PythonNetworkx构建一个图,我以以下节点位置为例(positions.txt):

节点ID,X,Y。我使用熊猫读取文件,并将位置设置为Networkx中的节点属性。使用
for
循环(无自边)中的
add_edge(id1,id2,weight)
方法添加节点。到目前为止,我假设默认情况下所有节点都相互连接,并且没有考虑节点的半径或距离等参数。
现在,我想使用这些节点位置计算节点之间的欧几里德半径或距离矩阵,并使用该矩阵,我想能够打印位于给定半径
n
内的节点的邻居,并将该文件保存为csv矩阵文件。一位朋友建议我使用
scipy
euclidean
方法,但我不知道如何使用它来构建矩阵,因此我没有起点。我尝试使用了
ego\u graph()
,但没有得到想要的结果。
在解决我的问题时,非常感谢任何帮助。
提前谢谢。(使用Ubuntu14.04 32位VM和Python 2.7)

您可以使用它生成给定坐标列表的距离矩阵

显然,numpy数组总是0索引的,如果您的节点有随机数,您需要保留一个它们的列表,以了解矩阵的哪一行/列对应于哪一对

之后你所做的应该是微不足道的,但我会根据你的描述给出一个例子。对于每个节点,打印所述节点的id以及阈值距离内任何相邻节点的id

import numpy as np
from scipy.spatial import distance

def neighbour_nodes_of(node, dist_matrix, distance):
    row = dist_matrix[node]
    return np.where((row <= distance) * (row > 0))[0]

ids = [1, 2, 3, 4, 5]
coords = [(21.5, 23),
          (24.5, 20),
          (19.5, 19),
          (22.5, 15),
          (24.5, 12),
          ]
threshold = 8.

dist_matrix = distance.cdist(coords, coords)

# this is something you can write to a file instead
for i, node_id in enumerate(ids):
    neighbours = neighbour_nodes_of(i, dist_matrix, threshold)
    neighbour_ids = [ids[n] for n in neighbours]
    print([node_id] + neighbour_ids)
将numpy导入为np
从scipy.spatial导入距离
定义相邻节点(节点、距离矩阵、距离):
行=距离矩阵[节点]
返回np.where((第0行))[0]
ids=[1,2,3,4,5]
coords=[(21.5,23),
(24.5, 20),
(19.5, 19),
(22.5, 15),
(24.5, 12),
]
阈值=8。
距离矩阵=距离.cdist(坐标,坐标)
#这是可以改为写入文件的内容
对于i,枚举中的节点_id(id):
邻居=邻居节点(i,距离矩阵,阈值)
邻居_id=[ids[n]表示邻居中的n]
打印([节点id]+邻居id)

节点对(i,j)的距离与(j,i)的距离相同,显然,如果一个在范围内,那么另一个也在范围内。当你保存数据时,你想要两个结果吗?@Reti43你说得很对。如果两个结果都被保存,那么它肯定会成为一个矩阵。我假设如果我只保存一个结果,那么它就像一个边缘列表。如果我能两者兼得最好,这样以后我就可以选择哪一个最适合我的实验了。还有一个问题,尽管它可能无关紧要。添加节点的
add_edge(id1,id2,weight)
的含义是什么?您可以使用
add_node()
简单地添加一个节点,然后将位置设置为属性,就像您之前描述的一句话一样。我使用2
for
for循环在
add_edge()
中添加节点,而不是多次使用
add_node()
,只是出于好奇(以及一点必要性),我还有一个问题:我正在循环运行
nx.draw
plt.show()
,以便在图形中重新创建边的添加和删除(就像电影一样)。但是,循环会导致输出与以前迭代中的所有边和节点重叠,并污损不需要的输出。您知道在每次迭代时“重新绘制”图形以避免上述问题的方法吗?再次感谢您的帮助:)@MFHS有多种动画显示方法,其中最关键的是在每个循环中调用
plt.cla()
,以清除当前轴。(您可能还需要调用
plt.gcf().canvas.draw()
)。如果您只需要检查一个较短的序列,但随着重绘次数的增加,时间越来越长,这通常是可以的。有关更多备选方案,请参阅
import numpy as np
from scipy.spatial import distance

def neighbour_nodes_of(node, dist_matrix, distance):
    row = dist_matrix[node]
    return np.where((row <= distance) * (row > 0))[0]

ids = [1, 2, 3, 4, 5]
coords = [(21.5, 23),
          (24.5, 20),
          (19.5, 19),
          (22.5, 15),
          (24.5, 12),
          ]
threshold = 8.

dist_matrix = distance.cdist(coords, coords)

# this is something you can write to a file instead
for i, node_id in enumerate(ids):
    neighbours = neighbour_nodes_of(i, dist_matrix, threshold)
    neighbour_ids = [ids[n] for n in neighbours]
    print([node_id] + neighbour_ids)