使用OSMNX向图中添加新节点时遇NaN错误及节点重复问题
问题分析与解决方案
核心问题1:节点重复(G2节点数翻倍)
原代码用nodes.append(my_nodes, ignore_index=True)重置了所有节点的索引为连续整数,但OSMNX的graph_from_gdfs默认将nodes的索引作为节点ID。而原edges中的u/v字段存储的是原路网节点的osmid(整数型索引),构建G2时,osmnx会自动根据edges中的u/v创建对应节点,同时保留nodes中所有以新索引为ID的节点,最终导致原节点被重复创建,节点数翻倍。
核心问题2:「Input contains NaN」错误
主要由两个原因导致:
- 原路网节点的
street_count字段可能存在NaN值,追加新节点后该列出现混合数据,构建图时部分节点属性含NaN,干扰后续空间计算; - 新添加的节点未连入路网,属于孤立节点,可能影响
nearest_nodes的距离计算逻辑。
修正后的代码
import networkx as nx import osmnx as ox import geopandas as gpd import pandas as pd from shapely.geometry import Point my_dict = { '001': { 'y': -31.640224888841907, 'x': -60.672566478771884, 'street_count': 1 } } # 构建新节点GeoDataFrame,将自定义osmid设为索引 tmp_list = [] index_list = [] for item_key, item_value in my_dict.items(): tmp_list.append({ 'geometry': Point(item_value['x'], item_value['y']), 'y': item_value['y'], 'x': item_value['x'], 'street_count': item_value['street_count'] }) index_list.append(item_key) my_nodes = gpd.GeoDataFrame(tmp_list, index=index_list) # 加载原路网 G = ox.graph_from_place("Santa Fe, Santa Fe, Argentina", network_type="drive", buffer_dist=5000) nodes = ox.graph_to_gdfs(G, nodes=True, edges=False) edges = ox.graph_to_gdfs(G, edges=True, nodes=False) # 合并节点:保留原索引,删除含NaN的冗余列 if 'street_count' in nodes.columns: nodes = nodes.drop(columns=['street_count']) nodes = pd.concat([nodes, my_nodes], axis=0) # 从GeoDataFrame重建图,明确使用索引作为节点ID G2 = ox.graph_from_gdfs(nodes, edges, node_id_as_index=True) # 计算最近节点与路径 dest = (-60.70916, -31.64553) ori = (-60.66756, -31.63719) iniciocercano = ox.nearest_nodes(G2, ori[0], ori[1], return_dist=True) finalcercano = ox.nearest_nodes(G2, dest[0], dest[1], return_dist=True) # 先检查两点连通性,避免无路径报错 if nx.has_path(G2, iniciocercano[0], finalcercano[0]): pathDistance = nx.shortest_path_length(G2, iniciocercano[0], finalcercano[0], weight="length") route = nx.shortest_path(G2, iniciocercano[0], finalcercano[0]) print(f"路径长度:{pathDistance}") else: print("两点间无连通路径")
关键修正点
- 避免节点重复:用
pd.concat合并节点,保留原节点的osmid索引,同时将新节点的索引设为自定义osmid,确保graph_from_gdfs使用索引作为节点ID时,与edges中的u/v完全匹配,不会重复创建节点; - 消除NaN属性:删除原节点中可能含NaN的
street_count列后再合并新节点的对应字段,避免属性列存在无效值; - 增加连通性检查:计算最短路径前先判断两点是否连通,避免因孤立节点或路网断开导致的错误;
- 明确节点ID规则:调用
graph_from_gdfs时指定node_id_as_index=True,确保节点ID逻辑清晰,与原路网结构兼容。
内容的提问来源于stack exchange,提问作者FG85
相关产品推荐
相关产品推荐

