You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

超大型图扁平化邻接矩阵计算的内存与性能优化求助

超大型有向图边重复次数统计优化方案

针对54327节点、4600万边的场景,以下是几种高效替代方案,解决内存溢出和速度过慢的问题:

方案1:NumPy 底层统计(最快+内存友好)

利用NumPy的unique函数直接对边数组做去重计数,底层C实现速度远优于Python循环,内存占用仅为原始边数组+结果集:

import numpy as np

# 将边列表转为int32类型的二维数组(节点数5万+,int32足够)
edges_np = np.array(edges_list, dtype=np.int32)
# 按行去重并统计次数
unique_edges, counts = np.unique(edges_np, axis=0, return_counts=True)
# 拼接为扁平化结果:[source, target, count]
result = np.column_stack((unique_edges, counts))

方案2:边读边统计(内存可控)

如果边数据存储在文件中,无需全量加载,用defaultdict逐行统计,内存占用等于唯一边的数量:

from collections import defaultdict

edge_counter = defaultdict(int)

# 逐行读取文件统计
with open('edges_data.txt', 'r') as f:
    for line in f:
        u, v = map(int, line.strip().split())
        edge_counter[(u, v)] += 1

# 转换为目标格式
result = [(u, v, cnt) for (u, v), cnt in edge_counter.items()]

方案3:Dask 分块计算(超大规模适配)

针对内存仍不足的场景,用Dask做分块并行统计,自动拆分数据块处理后合并结果:

import dask.bag as db

# 从文件读取边数据并转为元组
edge_bag = db.read_text('edges_data.txt').map(lambda line: tuple(map(int, line.strip().split())))
# 分块统计边频率
edge_counts = edge_bag.frequencies()
# 计算并转换结果
result = [(u, v, cnt) for (u, v), cnt in edge_counts.compute()]

方案4:数据库临时表统计(终极内存友好)

借助数据库的GROUP BY优化能力,内存开销极低,适合极端大的数据集:

import sqlite3

conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

# 创建临时表存储边数据
cursor.execute('CREATE TABLE edges (source INT, target INT)')
# 批量插入边(若数据量极大,可分批次插入)
cursor.executemany('INSERT INTO edges VALUES (?, ?)', edges_list)
# 统计重复次数
cursor.execute('SELECT source, target, COUNT(*) FROM edges GROUP BY source, target')
result = cursor.fetchall()

conn.close()

避坑提醒

  • 禁用NetworkX MultiDiGraph:维护节点/边对象结构的内存开销极大,完全不适合千万级边场景
  • 禁用pandas crosstab:会生成5万×5万的稠密矩阵(250亿元素),直接触发内存溢出
  • 禁用纯Python循环:4600万次循环的时间成本无法接受,必须用底层优化的实现

内容的提问来源于stack exchange,提问作者Eurico Covas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:52:42