【问题标题】:Python Scipy and Networkx: How to compute a Euclidean distance matrix?Python Scipy 和 Networkx:如何计算欧几里得距离矩阵?
【发布时间】:2018-03-28 01:28:11
【问题描述】:

我正在使用 Python Networkx 来构建图表,我有以下节点位置作为示例(positions.txt):

1 21.5 23
2 24.5 20
3 19.5 19
4 22.5 15
5 24.5 12  

节点 ID、X、Y。我使用 Pandas 读取文件并将位置设置为 Networkx 中的节点属性。在for 循环中使用add_edge(id1, id2, weight) 方法添加节点(没有自边缘)。到目前为止,我已经假设所有节点都默认相互连接,并且没有考虑节点的半径或距离等参数。
现在,我想使用这些节点位置计算节点之间的欧几里得半径或距离矩阵,并且使用这个矩阵,我希望能够打印落在给定半径n 内的节点的邻居并将文件保存为一个 csv 矩阵文件。一位朋友建议我使用scipyeuclidean 方法,但我不知道如何使用它来构建矩阵,因此我没有起点。我尝试使用ego_graph(),但它没有给我想要的结果。
任何帮助解决我的问题表示赞赏。
提前致谢。 (使用 Ubuntu 14.04 32 位 VM 和 Python 2.7)

【问题讨论】:

  • 节点对 (i, j) 的距离与 (j, i) 的距离相同,显然,如果一个在范围内,另一个也在范围内。保存数据时,您想要两个结果吗?
  • @Reti43 你说得很好。如果两个结果都保存了,那么它肯定会变成一个矩阵。我假设如果我只保存一个结果,那么它就像一个边缘列表。如果我能同时拥有这两者是最好的,以便以后我可以选择最适合我的实验。
  • 还有一个问题,尽管它可能无关紧要。 add_edge(id1, id2, weight)添加节点是什么意思?你可以简单地用add_node()添加一个节点,然后将位置设置为一个属性,就像你之前描述的一句话一样。
  • 我正在使用2个for循环在add_edge()中添加节点,而不是多次使用add_node()

标签: python matrix scipy networkx


【解决方案1】:

您可以使用scipy.spatial.distance.cdist() 在给定坐标列表的情况下生成距离矩阵。

显然,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)

【讨论】:

  • 另外,出于好奇(和一点点必要性),我还有一个问题:我正在循环运行nx.drawplt.show(),以便重新创建添加和删除图中的边(就像电影一样)。但是这些循环会导致输出与之前迭代的所有边和节点重叠,并且会影响不需要的输出。您是否知道在每次迭代时“重绘”图形以避免上述问题的方法/方法?再次感谢您的帮助:)
  • @MFHS 动画显示有多种方法,其中最粗暴的方法是在每个循环中调用plt.cla() 以清除当前轴。 (您可能还需要致电plt.gcf().canvas.draw())。如果您只需要检查一个短序列但随着更多重绘而变得越来越滞后,这通常是可以的。如需更多替代方案,请参阅animation API
猜你喜欢
  • 2016-08-02
  • 2020-06-16
  • 2015-01-13
  • 2014-05-08
  • 2012-06-27
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多