如何将Azure Cosmos DB图数据库转换为Python图对象?
解决Azure Cosmos DB图数据转NetworkX对象的问题
一、修复现有顶点提取代码的问题
你的代码返回空DataFrame的核心原因是**callback.result()只能被迭代一次**,第一次循环打印后,结果迭代器已经耗尽,第二次调用就返回空集合。另外代码里还有语法错误(username==应该是username=)。修复后的顶点提取代码如下:
from gremlin_python.driver import client, serializer import pandas as pd import networkx as nx def get_vertices(client): # 提交Gremlin查询,获取所有顶点及属性(含ID) query = "g.V().project('id','props').by(id()).by(valueMap().by(unfold())).toList()" callback = client.submitAsync(query) # 先将结果存入列表,避免迭代器耗尽 vertices_list = list(callback.result()) # 打印顶点信息 for v in vertices_list: print("\t", v) # 转换为DataFrame,展开props字段 vertices_df = pd.json_normalize(vertices_list) return vertices_df def get_edges(client): # 提交Gremlin查询,获取所有边及关联的起点、终点ID query = "g.E().project('source','target','props').by(outV().id()).by(inV().id()).by(valueMap().by(unfold())).toList()" callback = client.submitAsync(query) edges_list = list(callback.result()) # 打印边信息 for e in edges_list: print("\t", e) # 转换为DataFrame,展开props字段 edges_df = pd.json_normalize(edges_list) return edges_df if __name__ == "__main__": # 修正语法错误,补全参数格式 cosmos_client = client.Client( '<endpoint>', 'g', username="<username>", password="<password>", message_serializer=serializer.GraphSONSerializersV2d0() ) # 获取顶点数据 Vdata = get_vertices(cosmos_client) print("顶点DataFrame:") print(Vdata.head()) # 获取边数据 Edata = get_edges(cosmos_client) print("\n边DataFrame:") print(Edata.head())
二、将提取的数据转换为NetworkX图对象
有了结构化的顶点和边DataFrame后,可以直接构建NetworkX图:
# 初始化有向图(无向图用nx.Graph()) G = nx.DiGraph() # 添加顶点:以ID为节点标识,其余属性为节点属性 for idx, row in Vdata.iterrows(): node_id = row['id'] attrs = row.drop('id').to_dict() G.add_node(node_id, **attrs) # 添加边:根据起点、终点ID添加,附带边属性 for idx, row in Edata.iterrows(): source = row['source'] target = row['target'] edge_attrs = row.drop(['source','target']).to_dict() G.add_edge(source, target, **edge_attrs) # 验证图结构 print("\nNetworkX图节点数:", G.number_of_nodes()) print("NetworkX图边数:", G.number_of_edges())
关键注意事项
- Gremlin查询优化:必须显式获取顶点和边的ID,因为NetworkX依赖唯一标识来区分节点和关联边。
- 迭代器处理:
callback.result()返回的是一次性迭代器,必须先转为列表存储,才能多次使用(打印、转DataFrame)。 - 语法修正:原代码中
username=="<username>"是比较运算符,应改为赋值运算符username="<username>",同时函数参数之间要加逗号分隔。
内容的提问来源于stack exchange,提问作者StatStein
相关产品推荐
相关产品推荐

