调用osmnx.nearest_nodes触发pandas TypeError: Must pass list-like as `names`
问题描述
我需要获取起点的最近节点来计算最短路径,使用osmnx.nearest_nodes函数,代码如下:
orig_nodes = list(ox.nearest_nodes(G, brt_stops_reproj["x"],brt_stops_reproj["y"]))
但触发了TypeError: Must pass list-like as names错误,报错堆栈信息如下:
File ~\anaconda3\envs\geo_env\lib\site-packages\osmnx\utils_graph.py:58, in graph_to_gdfs(G, nodes, edges, node_geometry, fill_edge_geometry) 55 else: 56 gdf_nodes = gpd.GeoDataFrame(data, index=nodes) ---> 58 gdf_nodes.index.rename("osmid", inplace=True) 59 utils.log("Created nodes GeoDataFrame from graph") 61 if edges: File ~\anaconda3\envs\geo_env\lib\site-packages\pandas\core\indexes\base.py:1791, in Index.set_names(self, names, level, inplace) 1788 raise TypeError("Names must be a string when a single level is provided.") 1790 if not is_list_like(names) and level is None and self.nlevels > 1: ---> 1791 raise TypeError("Must pass list-like as `names`.") 1793 if is_dict_like(names) and not isinstance(self, ABCMultiIndex): 1794 raise TypeError("Can only pass dict-like as `names` for MultiIndex.") TypeError: Must pass list-like as `names`.
我认为错误源于函数脚本而非我的代码,因为pandas要求修改多列索引名需传入类列表参数,请问如何解决?
解决方法
这个问题是OSMnx与pandas版本兼容性导致的:当图的节点索引为**多级索引(MultiIndex)**时,OSMnx的graph_to_gdfs方法用字符串"osmid"重命名索引会触发pandas的规则校验(pandas要求多级索引重命名必须传入列表/类列表参数)。可通过以下方式解决:
方法1:调整OSMnx或pandas版本
- 若使用pandas 2.0+版本,直接升级OSMnx到v1.3.0及以上,该版本已修复此兼容性问题,会自动判断索引类型并传入对应格式的名称参数。
- 若不想升级OSMnx,可降级pandas到1.x版本,此版本允许用单字符串重命名多级索引。
方法2:手动修改OSMnx源码临时修复
找到报错文件osmnx/utils_graph.py,定位到第58行(对应报错位置):
gdf_nodes.index.rename("osmid", inplace=True)
将其替换为适配单级/多级索引的逻辑:
# 适配单级/多级索引的重命名规则 if gdf_nodes.index.nlevels > 1: gdf_nodes.index.rename(["osmid"] * gdf_nodes.index.nlevels, inplace=True) else: gdf_nodes.index.rename("osmid", inplace=True)
保存修改后重启Python环境即可生效。
方法3:提前处理图的索引,避免多级索引
在调用nearest_nodes前,将图的节点索引转为单级索引(业务场景允许的前提下):
# 提取节点和边的GeoDataFrame gdf_nodes, gdf_edges = ox.graph_to_gdfs(G) # 将多级索引转为单级(取第一级索引值) gdf_nodes.index = gdf_nodes.index.get_level_values(0) # 重新构建图 G = ox.graph_from_gdfs(gdf_nodes, gdf_edges)
处理完成后再调用ox.nearest_nodes就不会触发报错。
内容的提问来源于stack exchange,提问作者İsmail Sefa Esgün
相关产品推荐
相关产品推荐

