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

如何用Python生成共享Genre的Movie Node双向Edge List?

问题:生成电影共享类型的双向边列表

我正在用Python处理themoviedb.org的数据分析项目,要构建电影的网络图——节点是电影ID,两部电影只要共享同一个类型就建立双向边。

节点数据示例

nodes = [
    {'id': 315162, 'label': 'Puss in Boots: The Last Wish', 'genre_ids_1': '16', 'genre_ids_2': '28'},
    {'id': 536554, 'label': 'M3GAN', 'genre_ids_1': '878', 'genre_ids_2': '27'},
    {'id': 76600, 'label': 'Avatar: The Way of Water', 'genre_ids_1': '878', 'genre_ids_2': '12'},
    {'id': 653851, 'label': 'Devotion', 'genre_ids_1': '10752', 'genre_ids_2': '878'},
    {'id': 846433, 'label': 'The Enforcer', 'genre_ids_1': '28', 'genre_ids_2': '53'}
]

期望的双向边列表格式

source      target               genre_ids
315162      846433               28
846433      315162               28
76600       536554               878
76600       653851               878
536554      76600                878
...

现有无法实现需求的代码

genres=[28,12,16,35,80,99,18,10751,14,36,27,10402,9648,10749,878,10770,53,10752,37]
edges=[]
nodes = [{'id': 315162, 'label': 'Puss in Boots: The Last Wish', 'genre_ids_1':'16','genre_ids_2': '28'},{'id': 536554, 'label': 'M3GAN','genre_ids_1':'878','genre_ids_2': '27'},{'id': 76600, 'label': 'Avatar: The Way of Water','genre_ids_1':'878', 'genre_ids_2': '12'},{'id': 653851, 'label': 'Devotion','genre_ids_1': '10752', 'genre_ids_2': '878'},{'id': 846433, 'label': 'The Enforcer','genre_ids_1': '28', 'genre_ids_2': '53'}]
dictionary={}
def get_edges():
    for i in nodes:
        if i["genre_ids_1"] in genres:
                dictionary.setdefault(i['genre_ids_1'], []).append(i['label'])
        elif i["genre_ids_2"] in genres:
                dictionary.setdefault(i['genre_ids_2'], []).append(i['label'])
        if i["genre_ids_1"] in dictionary:
                if i["label"]  not in dictionary[ i["genre_ids_1"]][0]:
                    edges.append({"source":i["label"],"target":i["id"],"genre_id":dictionary[ i["genre_ids_1"]][0] })
        elif i["genre_ids_2"] in dictionary:
                if i["label"]  not in dictionary[ i["genre_ids_2"]][1]:
                    edges.append({"source":i["label"],"target":i["id"],"genre_id":dictionary[ i["genre_ids_2"]][1] })
    print(edges)
get_edges()     

解决方案

原代码问题分析

  1. 类型ID类型不匹配:节点中的类型ID是字符串,genres列表是整数,导致匹配判断失效
  2. 逻辑混乱:没有正确按类型分组电影ID,也未生成双向边
  3. 错误使用电影标题作为边的节点,需求要求用电影ID

修改思路

  1. 统一类型ID的格式,将genres转为字符串集合方便匹配
  2. 按类型分组所有电影ID
  3. 遍历每个类型下的电影ID列表,生成所有两两组合的双向边
  4. 按要求格式输出边列表

完整修改代码

genres = [28,12,16,35,80,99,18,10751,14,36,27,10402,9648,10749,878,10770,53,10752,37]
# 转换为字符串集合,匹配节点中的类型ID格式
genre_set = set(str(g) for g in genres)
nodes = [
    {'id': 315162, 'label': 'Puss in Boots: The Last Wish', 'genre_ids_1': '16', 'genre_ids_2': '28'},
    {'id': 536554, 'label': 'M3GAN', 'genre_ids_1': '878', 'genre_ids_2': '27'},
    {'id': 76600, 'label': 'Avatar: The Way of Water', 'genre_ids_1': '878', 'genre_ids_2': '12'},
    {'id': 653851, 'label': 'Devotion', 'genre_ids_1': '10752', 'genre_ids_2': '878'},
    {'id': 846433, 'label': 'The Enforcer', 'genre_ids_1': '28', 'genre_ids_2': '53'}
]

def get_edges():
    # 按类型分组电影ID
    genre_to_movies = {}
    for movie in nodes:
        movie_id = movie['id']
        # 收集当前电影的有效类型ID
        movie_genres = []
        if movie['genre_ids_1'] in genre_set:
            movie_genres.append(movie['genre_ids_1'])
        if movie['genre_ids_2'] in genre_set:
            movie_genres.append(movie['genre_ids_2'])
        
        # 将电影ID加入对应类型的列表
        for g in movie_genres:
            genre_to_movies.setdefault(g, []).append(movie_id)
    
    edges = []
    # 生成双向边
    for genre_id, movie_ids in genre_to_movies.items():
        # 遍历所有两两不同的电影组合
        for i in range(len(movie_ids)):
            for j in range(i+1, len(movie_ids)):
                source = movie_ids[i]
                target = movie_ids[j]
                # 添加正向和反向边
                edges.append({'source': source, 'target': target, 'genre_ids': genre_id})
                edges.append({'source': target, 'target': source, 'genre_ids': genre_id})
    
    # 按格式打印边列表
    print(f"{'source':<10} {'target':<15} {'genre_ids'}")
    for edge in edges:
        print(f"{edge['source']:<10} {edge['target']:<15} {edge['genre_ids']}")
    return edges

get_edges()

代码说明

  • 类型格式统一:将genres转为字符串集合,解决类型不匹配的问题
  • 类型分组:遍历每个电影,将其ID加入对应类型的分组列表
  • 双向边生成:对每个类型下的电影ID,生成所有两两组合的正向和反向边
  • 格式输出:用对齐格式打印边列表,符合需求样式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:25:32