OSMNX调用nearest_nodes报NaN错误,传入GeoDataFrame无空值如何解决
问题定位步骤
- 第一步:校验是否存在未检测到的无穷大值
你之前只检查了NaN,没有校验inf值,运行以下代码排查:
如果返回True的列就是存在无穷大值的字段,优先处理。import numpy as np print(gdf_nodes.apply(lambda x: np.isinf(x).any())) print(gdf_edges.apply(lambda x: np.isinf(x).any())) - 第二步:检查节点GeoDataFrame的必填字段是否符合OSMnx要求
OSMnx要求gdf_nodes必须包含x(存储经度,单位:度)、y(存储纬度,单位:度)两列,且节点的索引列是唯一的节点ID。运行以下代码校验:
如果你的节点经纬度列叫lon、lat,没有x、y,需要新增对应字段:print('gdf_nodes列名:', gdf_nodes.columns.tolist()) # 检查x、y列数值范围是否合规:纬度y范围[-90,90],经度x范围[-180,180] print('y列数值范围:', gdf_nodes['y'].min(), gdf_nodes['y'].max()) print('x列数值范围:', gdf_nodes['x'].min(), gdf_nodes['x'].max())gdf_nodes['x'] = gdf_nodes['lon'] gdf_nodes['y'] = gdf_nodes['lat'] - 第三步:检查nearest_nodes的参数是否传反
OSMnx的ox.nearest_nodes(G, X, Y)中,X是经度,Y是纬度,你给出的参数X=40.6943, Y=-74.011明显是经纬度传反了(纽约的纬度是北纬40.7,经度是西经74),如果图节点的x存的是经度、y存的是纬度,传反的话会导致查询坐标超出合理范围,触发数值错误。 - 第四步:校验边的索引节点是否都存在于节点表中
检查边的起始、目标节点ID是否全部在节点表的索引中,避免构建图时生成孤立无坐标的节点:
大于0的话需要先处理边表的异常节点ID。all_nodes = gdf_nodes.index.tolist() print('边起始节点不存在于节点表的数量:', (~gdf_edges['FRFRANODE'].isin(all_nodes)).sum()) print('边目标节点不存在于节点表的数量:', (~gdf_edges['TOFRANODE'].isin(all_nodes)).sum()) - 第五步:检查坐标系是否合规
如果你的gdf_nodes的坐标参考系不是WGS84(EPSG:4326),x/y列的数值会是投影后的米级数值,范围远超经纬度的合理区间,也会触发报错,运行以下代码校验:
如果不是EPSG:4326,先转换坐标系:print(gdf_nodes.crs)gdf_nodes = gdf_nodes.to_crs(epsg=4326) gdf_edges = gdf_edges.to_crs(epsg=4326)
修复后的代码示例
import osmnx as ox import networkx as nx import numpy as np # 1. 预处理节点表,确保存在x、y列(假设你原来的经纬度列是lon、lat,按需修改列名) gdf_nodes['x'] = gdf_nodes['lon'] gdf_nodes['y'] = gdf_nodes['lat'] # 2. 排除所有inf值 gdf_nodes = gdf_nodes.replace([np.inf, -np.inf], np.nan).dropna() gdf_edges = gdf_edges.replace([np.inf, -np.inf], np.nan).dropna() # 3. 转换坐标系为WGS84 gdf_nodes = gdf_nodes.to_crs(epsg=4326) gdf_edges = gdf_edges.to_crs(epsg=4326) # 4. 构建图 G = ox.graph_from_gdfs(gdf_nodes, gdf_edges.set_index(['FRFRANODE', 'TOFRANODE', 'FRAARCID']), graph_attrs=None) # 5. 正确传参:X传经度,Y传纬度,调整原参数的顺序 # 纽约点:经度-74.011049,纬度40.694384 source = ox.nearest_nodes(G, X=-74.011049120926, Y=40.694384761057826) # 洛杉矶点:经度-118.190618,纬度33.755099 target = ox.nearest_nodes(G, X=-118.19061812233898, Y=33.755099145658) # 6. 计算最短路径 weight = "MILES" route = nx.shortest_path(G, source, target, weight=weight) route_length = nx.shortest_path_length(G, source, target, weight=weight)
内容的提问来源于stack exchange,提问作者bili
相关产品推荐
相关产品推荐

