使用Numpy数组创建NetworkX图进程被终止,如何优化内存占用?
优化NetworkX从稠密相似度矩阵创建图的内存问题
你的问题核心不是节点数(20K节点不算多),而是稠密矩阵会生成4亿条边(20K×20K),这才是内存暴涨的根源。NetworkX能处理百万节点的前提是稀疏图(边数远小于全连接数),全连接的稠密图必然会耗尽内存。以下是具体优化方法:
1. 过滤低相似度边(最有效)
只保留相似度超过阈值的边,直接压缩边的数量:
import numpy as np import networkx as nx # 设定相似度阈值,根据业务需求调整 similarity_threshold = 0.6 # 提取所有符合条件的边索引和权重 row_indices, col_indices = np.where(similarity_matrix > similarity_threshold) edge_weights = similarity_matrix[row_indices, col_indices] # 构造带权重的边列表 edges = [ (row, col, {"weight": weight}) for row, col, weight in zip(row_indices, col_indices, edge_weights) ] # 创建图并添加边 graph = nx.Graph() graph.add_edges_from(edges)
这种方法能把边数从4亿压缩到几万/几十万量级,内存占用会大幅下降。
2. 使用稀疏矩阵作为输入
将稠密矩阵转换为Scipy稀疏矩阵,NetworkX会自动忽略零值元素,只存储有效边:
import scipy.sparse as sp import networkx as nx # 把稠密矩阵转为CSR格式的稀疏矩阵 sparse_sim_matrix = sp.csr_matrix(similarity_matrix) # 从稀疏矩阵创建图 graph = nx.from_scipy_sparse_matrix(sparse_sim_matrix)
如果你的相似度矩阵本身有大量零值(或极小值),这种方法能直接减少内存占用,无需手动过滤。
3. 避免重复存储无向边
如果你的相似度矩阵是对称的(无向图场景),可以只保留上三角/下三角的边,避免存储双向重复边:
import numpy as np import networkx as nx # 只保留上三角区域(不含对角线)的边 row_indices, col_indices = np.triu_indices_from(similarity_matrix, k=1) mask = similarity_matrix[row_indices, col_indices] > similarity_threshold filtered_rows = row_indices[mask] filtered_cols = col_indices[mask] filtered_weights = similarity_matrix[filtered_rows, filtered_cols] edges = [ (r, c, {"weight": w}) for r, c, w in zip(filtered_rows, filtered_cols, filtered_weights) ] graph = nx.Graph() graph.add_edges_from(edges)
这能进一步减少一半的边数(对称矩阵场景下)。
关键提醒
NetworkX的内存占用主要由边的数量决定,而非节点数。20K节点的全连接图有4亿条边,每条边需要存储节点ID和权重,这至少需要几十GB内存,远超常规机器的承受能力。所以优化的核心永远是减少无效边的数量。
内容的提问来源于stack exchange,提问作者An old man in the sea.
相关产品推荐
相关产品推荐

