如何将具有复数权重的 NetworkX 图转换为矩阵?
How to convert a NetworkX graph with complex weights to a matrix?
我有一张图,其权重是复数。 networkx
有一些函数可以将图形转换为边权矩阵,但是,它似乎不适用于复数(尽管反向转换工作正常)。似乎需要 int
或 float
边权重才能将它们转换为 NumPy array/matrix.
Python 3.9.7 | packaged by conda-forge | (default, Sep 29 2021, 19:20:46)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.29.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import numpy as np
In [2]: import networkx as nx
In [3]: X = np.random.normal(size=(5,5)) + 1j*np.random.normal(size=(5,5))
In [4]: X
Out[4]:
array([[ 1.64351378-0.83369888j, -2.29785353-0.86089473j,
...
...
0.50504368-0.67854997j, -0.29049118-0.48822688j,
0.22752377-1.38491981j]])
In [5]: g = nx.DiGraph(X)
In [6]: for i,j in g.edges(): print(f"{(i,j)}: {g[i][j]['weight']}")
(0, 0): (1.6435137789271903-0.833698877745345j)
...
(4, 4): (0.2275237661137745-1.3849198099771993j)
# So conversion from matrix to nx.DiGraph works just fine.
# But the other way around gives an error.
In [7]: Z = nx.to_numpy_array(g, dtype=np.complex128)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-b0b717e5ec8a> in <module>
----> 1 Z = nx.to_numpy_array(g, dtype=np.complex128)
~/miniconda3/envs/coupling/lib/python3.9/site-packages/networkx/convert_matrix.py in to_numpy_array(G, nodelist, dtype, order, multigraph_weight, weight, nonedge)
1242 for v, d in nbrdict.items():
1243 try:
-> 1244 A[index[u], index[v]] = d.get(weight, 1)
1245 except KeyError:
1246 # This occurs when there are fewer desired nodes than
TypeError: can't convert complex to float
我查看了文档,它似乎只是说这仅适用于简单的 NumPy 数据类型和复合类型,应该使用 recarrays。我不太了解 recarrays,使用 np.to_numpy_recarray
也会产生错误。
In [8]: Z = nx.to_numpy_recarray(g, dtype=np.complex128)
...
TypeError: 'NoneType' object is not iterable
那么问题来了,如何将图正确的转化为边权矩阵呢?
下面是一个快速技巧,在实施修复之前可能会有用:
import networkx as nx
import numpy as np
def to_numpy_complex(G):
# create an empty array
N_size = len(G.nodes())
E = np.empty(shape=(N_size, N_size), dtype=np.complex128)
for i, j, attr in G.edges(data=True):
E[i, j] = attr.get("weight")
return E
X = np.random.normal(size=(5, 5)) + 1j * np.random.normal(size=(5, 5))
g = nx.DiGraph(X)
Y = to_numpy_complex(g)
print(np.allclose(X, Y)) # True
我有一张图,其权重是复数。 networkx
有一些函数可以将图形转换为边权矩阵,但是,它似乎不适用于复数(尽管反向转换工作正常)。似乎需要 int
或 float
边权重才能将它们转换为 NumPy array/matrix.
Python 3.9.7 | packaged by conda-forge | (default, Sep 29 2021, 19:20:46)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.29.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import numpy as np
In [2]: import networkx as nx
In [3]: X = np.random.normal(size=(5,5)) + 1j*np.random.normal(size=(5,5))
In [4]: X
Out[4]:
array([[ 1.64351378-0.83369888j, -2.29785353-0.86089473j,
...
...
0.50504368-0.67854997j, -0.29049118-0.48822688j,
0.22752377-1.38491981j]])
In [5]: g = nx.DiGraph(X)
In [6]: for i,j in g.edges(): print(f"{(i,j)}: {g[i][j]['weight']}")
(0, 0): (1.6435137789271903-0.833698877745345j)
...
(4, 4): (0.2275237661137745-1.3849198099771993j)
# So conversion from matrix to nx.DiGraph works just fine.
# But the other way around gives an error.
In [7]: Z = nx.to_numpy_array(g, dtype=np.complex128)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-b0b717e5ec8a> in <module>
----> 1 Z = nx.to_numpy_array(g, dtype=np.complex128)
~/miniconda3/envs/coupling/lib/python3.9/site-packages/networkx/convert_matrix.py in to_numpy_array(G, nodelist, dtype, order, multigraph_weight, weight, nonedge)
1242 for v, d in nbrdict.items():
1243 try:
-> 1244 A[index[u], index[v]] = d.get(weight, 1)
1245 except KeyError:
1246 # This occurs when there are fewer desired nodes than
TypeError: can't convert complex to float
我查看了文档,它似乎只是说这仅适用于简单的 NumPy 数据类型和复合类型,应该使用 recarrays。我不太了解 recarrays,使用 np.to_numpy_recarray
也会产生错误。
In [8]: Z = nx.to_numpy_recarray(g, dtype=np.complex128)
...
TypeError: 'NoneType' object is not iterable
那么问题来了,如何将图正确的转化为边权矩阵呢?
下面是一个快速技巧,在实施修复之前可能会有用:
import networkx as nx
import numpy as np
def to_numpy_complex(G):
# create an empty array
N_size = len(G.nodes())
E = np.empty(shape=(N_size, N_size), dtype=np.complex128)
for i, j, attr in G.edges(data=True):
E[i, j] = attr.get("weight")
return E
X = np.random.normal(size=(5, 5)) + 1j * np.random.normal(size=(5, 5))
g = nx.DiGraph(X)
Y = to_numpy_complex(g)
print(np.allclose(X, Y)) # True