从 Python 中的 2 个 numpy 数组创建无向和加权图
Creating undirected and weighted graph from 2 numpy arrays in Python
在每次 for 循环迭代中,我不断生成 2 组 numpy 数组。让我们调用第一个 numpy 数组 'A' 和第二个 numpy 数组 'B'.
所以 A 看起来像这样,其中 A 的长度可以变化:
[[ 0.94 -0.04]
[ 0.94 -0.03]
[ 0.98 -0.01]
[ 0.98 0. ]
[ 0.98 0.01]
[ 0.99 0.01]
[ 0.99 0.02]
[ 0.99 0.03]
[ 0.99 0.04]
[ 0.99 0.94]
[ 0.99 0.95]]
设A中的每个'vector'为无向带权图的一个节点,例如[0.94 -0.04]是一个节点,[0.94 -0.03]是另一个节点等等。
B 看起来像并且只会采用 [X,Y]:
的格式
[ 0.99 -0.01]
其中[0.99 -0.01]是另一个节点
现在我需要创建一个无向加权图,使得 [0.99 -0.01] 连接到 numpy 数组 A 中的每个节点,两个节点向量之间的权重为给定的数学公式。
例如。
[ 0.99 -0.01] connected to [ 0.94 -0.04] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.04])
[ 0.99 -0.01] connected to [ 0.94 -0.03] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.03])
And so on...
现在,最后一个条件是,在每次 for 循环迭代之后,您可能会得到向量组合,使得连接已经存在于图中(即向量组合的重复),在这种情况下,我们需要忽略并只寻找向量组合,这样图形就没有了,并附加图形以连接这两个具有给定权重的向量。
有人可以帮忙制定一个理想的解决方案吗?谢谢。
您收到的错误是因为 numpy.array
是可变类型,因此不可散列(请参阅 Python glossary 中的 "hashable" 条目)。如果我没记错的话 networkx
使用字典来表示引擎盖下的图形,所以我将使用 Python dict
来展示示例解决方案。如果您尝试使用 numpy.array
作为 dict
中的键,您会得到相同的 "unhashable type" 错误:
import numpy as np
b = np.array((1,2))
a = {b:"value"}
一种可能的解决方案是将其转换为不可变类型,例如元组。以下将起作用:
import numpy as np
b = np.array((1,2))
a = {tuple(b):"value"}
考虑到这一点,让我们用 networkx
:
创建一个无向图
import networkx as nx
import numpy as np
#generate some random data
a = np.random.randint(low=1, high=10,size=(4,2))
b = np.random.randint(low=1, high=10,size =(2,))
#create a undirected graph
g = nx.graph.Graph()
# define a function that takes two arrays and returns a scalar -- weight
def w(a,b):
return np.linalg.norm(b - a)
# cast np.arrays as tuples and use w to compute weights to get a list of edges
edges = [(tuple(x), tuple(b), w(x,b)) for x in a]
# add weighted edges to the graph
g.add_weighted_edges_from(edges)
# check if it worked (for a small sample)
for x in g.adjacency():
print(x)
注意因为图是无向的,一对节点(一条边)会出现两次,所以从a到b的一条无向边,会出现两条边(a,b)和(b,a)。
在每次 for 循环迭代中,我不断生成 2 组 numpy 数组。让我们调用第一个 numpy 数组 'A' 和第二个 numpy 数组 'B'.
所以 A 看起来像这样,其中 A 的长度可以变化:
[[ 0.94 -0.04]
[ 0.94 -0.03]
[ 0.98 -0.01]
[ 0.98 0. ]
[ 0.98 0.01]
[ 0.99 0.01]
[ 0.99 0.02]
[ 0.99 0.03]
[ 0.99 0.04]
[ 0.99 0.94]
[ 0.99 0.95]]
设A中的每个'vector'为无向带权图的一个节点,例如[0.94 -0.04]是一个节点,[0.94 -0.03]是另一个节点等等。
B 看起来像并且只会采用 [X,Y]:
的格式[ 0.99 -0.01]
其中[0.99 -0.01]是另一个节点
现在我需要创建一个无向加权图,使得 [0.99 -0.01] 连接到 numpy 数组 A 中的每个节点,两个节点向量之间的权重为给定的数学公式。
例如。
[ 0.99 -0.01] connected to [ 0.94 -0.04] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.04])
[ 0.99 -0.01] connected to [ 0.94 -0.03] with scalar weight np.linalg.norm([ 0.99 -0.01] - [ 0.94 -0.03])
And so on...
现在,最后一个条件是,在每次 for 循环迭代之后,您可能会得到向量组合,使得连接已经存在于图中(即向量组合的重复),在这种情况下,我们需要忽略并只寻找向量组合,这样图形就没有了,并附加图形以连接这两个具有给定权重的向量。
有人可以帮忙制定一个理想的解决方案吗?谢谢。
您收到的错误是因为 numpy.array
是可变类型,因此不可散列(请参阅 Python glossary 中的 "hashable" 条目)。如果我没记错的话 networkx
使用字典来表示引擎盖下的图形,所以我将使用 Python dict
来展示示例解决方案。如果您尝试使用 numpy.array
作为 dict
中的键,您会得到相同的 "unhashable type" 错误:
import numpy as np
b = np.array((1,2))
a = {b:"value"}
一种可能的解决方案是将其转换为不可变类型,例如元组。以下将起作用:
import numpy as np
b = np.array((1,2))
a = {tuple(b):"value"}
考虑到这一点,让我们用 networkx
:
import networkx as nx
import numpy as np
#generate some random data
a = np.random.randint(low=1, high=10,size=(4,2))
b = np.random.randint(low=1, high=10,size =(2,))
#create a undirected graph
g = nx.graph.Graph()
# define a function that takes two arrays and returns a scalar -- weight
def w(a,b):
return np.linalg.norm(b - a)
# cast np.arrays as tuples and use w to compute weights to get a list of edges
edges = [(tuple(x), tuple(b), w(x,b)) for x in a]
# add weighted edges to the graph
g.add_weighted_edges_from(edges)
# check if it worked (for a small sample)
for x in g.adjacency():
print(x)
注意因为图是无向的,一对节点(一条边)会出现两次,所以从a到b的一条无向边,会出现两条边(a,b)和(b,a)。