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

如何优化Python中嵌套读取JSON构建图书关联图的耗时

优化图书关联图构建的高效方案

原代码的问题核心是嵌套遍历整个数据集两次,时间复杂度直接拉到O(n²),5万条数据就是25亿次循环,效率必然极低。再加上每次内层循环都重复打开文件,额外增加了IO开销,必须重构。

优化思路

先按user_id分组,把每个用户读过的所有book_id收集到一起,再对每个用户的图书列表生成所有两两组合,直接添加边。这样只需要遍历数据集一次,后续的组合操作只针对每个用户的图书集合,时间复杂度会大幅降低。

优化后的代码

import jsonlines
import networkx as nx
from itertools import combinations

G2 = nx.Graph()
user_books = {}

# 第一步:遍历一次文件,构建用户-图书映射
with jsonlines.open('filtered_data.json', 'r') as reader:
    for idx, obj in enumerate(reader, 1):
        user_id = obj["user_id"]
        book_id = obj["book_id"]
        # 把当前用户的图书加入对应的列表
        if user_id not in user_books:
            user_books[user_id] = []
        user_books[user_id].append(book_id)
        # 可选:打印进度,避免长时间无反馈
        if idx % 1000 == 0:
            print(f"已处理 {idx} 条数据")

# 第二步:遍历每个用户的图书列表,生成两两组合添加边
for books in user_books.values():
    # 只有当用户读过至少2本书时才需要生成组合
    if len(books) >= 2:
        # 用combinations生成所有不重复的两两组合
        for book_pair in combinations(books, 2):
            G2.add_edge(*book_pair)

print(f"图构建完成,节点数:{G2.number_of_nodes()},边数:{G2.number_of_edges()}")

额外优化建议

  • 如果存在同一用户重复记录同一本书的情况,可以先对每个用户的book_id去重,比如把user_books[user_id]改成集合再转列表:user_books[user_id] = list(set(user_books[user_id])),避免做无用的重复边添加操作(不过nx.Graph会自动忽略重复边,只是浪费一点计算资源)。
  • 若数据集远超5万条,可以考虑结合内存映射或分块读取,但针对当前规模,上述代码足以秒级完成构建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:21:07