我想在python中创建一个nxn对称矩阵。让我们说n = 9,然后我想要下面的东西:
array[[0,1,0,0,0,1,1,0,1],[1,0,1,1,1,0,0,0,0],[0,1,0,1,1,0,0,0,0]….].
我知道如何通过首先在python(np.zeros((9,9))中创建一个nun零矩阵然后使用循环来填充它1和零来实现这一点。但我觉得这不是pythonic方式因此,如果矩阵很大,那么寻找使用循环的优化方法会减慢代码。
基本上它是我为无向图创建的邻接矩阵。我的后续问题是如何绘制一个具有邻接矩阵的图形。从邻接矩阵绘制无向图的任何函数?
请指教。我想学习python中最好的/ pythonic方法,而不是使用传统的循环。
编辑:
我使用以下内容为30x30邻接矩阵创建边缘列表。但是此边缘列表没有集群中每个节点的对。如果我开始这样做,列表将是巨大的。因此,我的下图在群集中的每个节点之间没有边缘。如何自动化此边列表,以便我不必手动键入所有边对。在图中,我希望群集中的每个节点与该群集中的其他节点具有边缘,并且只有节点1和2应该在群集边缘与节点16和其他群集的17之间。
N=30
# Creating a matrix of zeros.
W=np.zeros((N,N))
# Mentioning the edges to start with. Thinking of a pair of 15 node cluster with two cluster connected by two pair of nodes.
edge=[[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[1,11],[1,12],[1,13],[1,14],[1,15],
[16,17],[16,18],[16,19],[16,20],[16,21],[16,22],[16,23],[16,24],[16,25],[16,26],[16,27],[16,28],[16,29],[16,30],
[1,16],[2,17]]
# Function for creating adjacency matrix ,populating the zeros matrix with 1 and 0-signifying edges on a node.
def adjacencyMatrix():
"""This function creates an Adjacency Matrix from a edge set.
input-> set of edges to be connected
output-> Adjacency matrix (n,n)
"""
for first,second in edge:
W[first-1,second-1]=W[second-1][first-1]=1
图表:
答案 0 :(得分:1)
如果您只关心图形和邻接矩阵,您是否必须从矩阵构建图形?或者你是否乐意以相反的方式做到这一点?
你应该看看networkx
。
铭记评论;你有一组边缘 - 你事先知道这些(或至少你想要如何创建它们 - 和你想要绘制图形。现在,如果你想要你可以单独创建邻接矩阵,像这样:
A = [[0 for _ in range(N)] for _ in range(N)]
edges = [[1,2], [3,4], [6,1], ..., etc.]
for start, finish in edges:
A[start][finish] = A[finish][start] = 1
然后你可以按照下面的方式进行绘图 - 但是当你从networkx
获得所有功能时,你为什么要这样做呢?你通过告诉它有什么边缘来创建一个adjecency矩阵 - 图形和邻接矩阵保存完全相同的信息,只是以不同的格式,它没有区别你这样做(并且可以说通过添加它来做它图表的边缘也更具可读性。
在编辑中,您希望拥有两个节点集群,然后让每个集群中的所有节点相互连接,然后再添加几个边缘。你提到手动执行此操作会很乏味,而且你是对的:所以以编程方式执行此操作。
import networkx as nx
from matplotlib import pyplot
G=nx.Graph()
# Why not group your nodes into clusters, since that's how you plan on using them.
node_clusters = [range(10), range(10,20)]
for node_cluster in node_clusters:
for node in node_cluster:
for other_node in node_cluster:
if node != other_node:
G.add_edge(node, other_node) # we don't actually need to add nodes, as the `add_edge` will add the nodes for us.
#Add manual edges
G.add_edge(0,10)
G.add_edge(1, 11)
from networkx.linalg.graphmatrix import adjacency_matrix
A = adjacency_matrix(G)
print A
nx.draw(G)
pyplot.show()
老实说,如果每个群集中的每个节点都相互连接,那么实际上并没有大量的点绘制所有连接,而是在更大的节点上总结它们可能会更好地绘制。
答案 1 :(得分:0)
邻接矩阵通常是稀疏的(nnz ~ O(N)
),因此它们通常存储在sparse format中。最简单的一种是基本上是三个数组的格式:[row_ids, col_id, value]
,crs和csc稍微复杂一些,但具有更高的性能。使用稀疏表示的核心好处是,当你开始执行时,可以说,matvec通常可以获得巨大的加速(在假设nnz ~ O(N)
下渐近复杂度较低)。
回答你的问题:你可以使用pos = [(1, 4), (3, 2)]
这样的位置构建矩阵,如下所示:
M = scipy.sparse.coo_matrix(([1]*len(pos), zip(*pos)))
在我看来几乎是Pythonic:)