简体   繁体   English

从 Python 中的 2 numpy arrays 创建无向加权图

[英]Creating undirected and weighted graph from 2 numpy arrays in Python

Within each for loop iteration I keep generating 2 sets of numpy arrays.在每个 for 循环迭代中,我不断生成 2 组 numpy arrays。 Let's call the first numpy array 'A' and the second numpy array 'B'.我们称第一个 numpy 数组为“A”,第二个 numpy 数组为“B”。

So A could look something like, where the length of A can vary:所以 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]]

Let each 'vector' in A be a node of an undirected and weighted graph, so for eg [ 0.94 -0.04] is a node, [ 0.94 -0.03] is another node and so on.假设 A 中的每个“向量”都是无向加权图的一个节点,例如 [0.94 -0.04] 是一个节点,[0.94 -0.03] 是另一个节点,依此类推。

And B would look something like and will only take the format of [X,Y]: B 看起来像并且只会采用 [X,Y] 的格式:

[ 0.99 -0.01]

Where [ 0.99 -0.01] is another node其中 [ 0.99 -0.01] 是另一个节点

Now I need to create an undirected and weighted graph such that [ 0.99 -0.01] is connected to each of the nodes in numpy array A, with a weight of given mathematical formula between the two node vectors.现在我需要创建一个无向加权图,使得 [0.99 -0.01] 连接到 numpy 数组 A 中的每个节点,两个节点向量之间具有给定数学公式的权重。

For eg.例如。

[ 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...

Now, the last condition is that after each for loop iteration you may get combinations of vectors such that the connection already exists in the graph (ie repeat of combination of vectors), which in that case we need to ignore and only look for vector combinations such that the graph does not already have and append the graph to make a connection of those two vectors with a given weight.现在,最后一个条件是,在每次 for 循环迭代之后,您可能会得到向量组合,使得连接已经存在于图中(即向量组合的重复),在这种情况下,我们需要忽略并只寻找向量组合这样该图还没有 append 该图以给定权重连接这两个向量。

Can someone please help with formulating an ideal solution?有人可以帮助制定理想的解决方案吗? Thanks.谢谢。

The error you're getting is because numpy.array is a mutable type, and hence not hashable (see "hashable" entry in the Python glossary ).您收到的错误是因为numpy.array是可变类型,因此不可散列(请参阅Python 词汇表中的“散列”条目)。 If I'm not mistaken networkx uses dictionaries to represent graphs under the hood, so I'll use Python dict to showcase an example solution.如果我没记错networkx使用字典来表示引擎盖下的图形,那么我将使用 Python dict来展示示例解决方案。 If you try to use a numpy.array as a key in a dict you're get the same "unhashable type" error:如果您尝试使用numpy.array作为dict中的键,则会收到相同的“不可散列类型”错误:

import numpy as np

b = np.array((1,2))
a = {b:"value"}

A possible solution is to convert it to an immutable type, for example, a tuple.一种可能的解决方案是将其转换为不可变类型,例如元组。 The following would work:以下将起作用:

import numpy as np

b = np.array((1,2))
a = {tuple(b):"value"}

With that in mind, let's create an undirected graph with networkx :考虑到这一点,让我们用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)

Note that because the graph is undirected a pair of nodes (an edge) will appear twice, so an undirected edge from a to b, will appear as two edges (a,b) and (b,a).请注意,由于图是无向的,一对节点(一条边)将出现两次,因此从 a 到 b 的无向边将显示为两条边 (a,b) 和 (b,a)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM