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

使用graph_from_gdfs重建图后调用OSMnx simplify_graph抛TypeError

问题:如何避免Osmnx简化图时的TypeError并成功简化重建后的图?

问题背景

工作流如下:
ox.graph_from_polygon => graph_to_gdfs => 修改gdf_edges => ox.graph_from_gdfs => ox.simplify_graph

执行到ox.simplify_graph时抛出TypeError: unhashable type: 'list',错误位置在Osmnx的simplification.py第362行:

File .../osmnx/simplification.py:362, in simplify_graph(G, strict, edge_attrs_differ, endpoint_attrs, remove_rings, track_merged)
    359 if attr in attrs_to_sum:
    360     # if this attribute must be summed, sum it now
    361     path_attributes[attr] = sum(path_attributes[attr])
--> 362 elif len(set(path_attributes[attr])) == 1:
    363     # if there's only 1 unique value in this attribute list,

即使未修改数据框也会触发该错误,最小复现示例:

import shapely
import osmnx as ox

poly = shapely.from_wkt("POLYGON((9.493474960327147 51.228210969202365,"
                        "9.493346214294432 51.223359875812804,"
                        "9.498442411422728 51.22356145497176,"
                        "9.498571157455443 51.228036284963565,"
                        "9.493474960327147 51.228210969202365))")

G = ox.graph_from_polygon(poly, network_type="drive")

nodes_gdf, edges_gdf = ox.graph_to_gdfs(G.to_undirected())

G2 = ox.graph_from_gdfs(gdf_nodes=nodes_gdf, gdf_edges=edges_gdf)

nodes_gdf_2, edges_gdf_2 = ox.graph_to_gdfs(ox.simplify_graph(G2))

错误原因

问题源于无向图转换后的边属性类型异常:调用G.to_undirected()后,部分原本为单一值的边属性(如oneway)会被转为列表类型。而ox.simplify_graph在处理属性时,会尝试将属性值存入集合(set(path_attributes[attr])),但列表是不可哈希类型,直接存入集合就会触发该TypeError。

解决方法

方案1:放弃无向图转换(如果业务允许)

直接去掉G.to_undirected(),保持原图的有向性,重建后即可正常简化:

import shapely
import osmnx as ox

poly = shapely.from_wkt("POLYGON((9.493474960327147 51.228210969202365,"
                        "9.493346214294432 51.223359875812804,"
                        "9.498442411422728 51.22356145497176,"
                        "9.498571157455443 51.228036284963565,"
                        "9.493474960327147 51.228210969202365))")

G = ox.graph_from_polygon(poly, network_type="drive")

nodes_gdf, edges_gdf = ox.graph_to_gdfs(G)  # 移除to_undirected()

G2 = ox.graph_from_gdfs(gdf_nodes=nodes_gdf, gdf_edges=edges_gdf)

nodes_gdf_2, edges_gdf_2 = ox.graph_to_gdfs(ox.simplify_graph(G2))

方案2:处理无向图的列表类型属性(如果必须使用无向图)

在重建图之前,将边属性中的列表类型转换为可哈希的单一值。以oneway为例,取列表第一个元素(或根据业务逻辑合并):

import shapely
import osmnx as ox

poly = shapely.from_wkt("POLYGON((9.493474960327147 51.228210969202365,"
                        "9.493346214294432 51.223359875812804,"
                        "9.498442411422728 51.22356145497176,"
                        "9.498571157455443 51.228036284963565,"
                        "9.493474960327147 51.228210969202365))")

G = ox.graph_from_polygon(poly, network_type="drive")

nodes_gdf, edges_gdf = ox.graph_to_gdfs(G.to_undirected())

# 处理列表类型的边属性
edges_gdf['oneway'] = edges_gdf['oneway'].apply(lambda x: x[0] if isinstance(x, list) else x)
# 其他可能转为列表的属性(如lanes、access等)需同理处理
# edges_gdf['lanes'] = edges_gdf['lanes'].apply(lambda x: x[0] if isinstance(x, list) else x)

G2 = ox.graph_from_gdfs(gdf_nodes=nodes_gdf, gdf_edges=edges_gdf)

nodes_gdf_2, edges_gdf_2 = ox.graph_to_gdfs(ox.simplify_graph(G2))

方案3:无向图转换时禁用属性列表化

调用to_undirected()时指定reciprocal=False,避免属性被转为列表,但这会改变无向化的逻辑(不会添加反向边),需根据需求选择:

nodes_gdf, edges_gdf = ox.graph_to_gdfs(G.to_undirected(reciprocal=False))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:05:05