如何合并多份含重叠数据的路网Excel文件?
解决路段数据细分合并的可行思路
嘿,这个把多份路网表合并成细分路段的需求确实有点绕,但其实可以拆解成几个清晰的步骤来实现,我给你梳理下具体的思路和Python代码示例:
问题核心分析
你需要把同一条道路的所有路段断点(来自路面、质量、交通量三个表的From和To)全部收集起来,把整条路拆分成最小的连续子路段,然后给每个子路段匹配三个表中对应的属性值。
具体实现步骤(用Pandas处理更高效)
首先,我们用Pandas来读取和处理数据,比openpyxl+SQLite的组合更适合这种场景:
1. 读取并预处理数据
先把Excel文件读进来,还要把逗号格式的小数转换成数值类型(不然排序会出问题):
import pandas as pd # 读取三个Excel表 pavement_df = pd.read_excel("路面信息表.xlsx") quality_df = pd.read_excel("质量信息表.xlsx") traffic_df = pd.read_excel("交通量信息表.xlsx") # 转换逗号分隔的小数为数值类型 def fix_decimal(value): return float(str(value).replace(",", ".")) # 给三个表的From/To列做转换 for df in [pavement_df, quality_df, traffic_df]: df["From"] = df["From"].apply(fix_decimal) df["To"] = df["To"].apply(fix_decimal)
2. 按道路分组整理数据
把每个表的数据按Road分组,方便后续单独处理每条道路:
# 按Road分组,把每组转换成字典列表(方便后续遍历) pavement_groups = pavement_df.groupby("Road").apply(lambda x: x.to_dict("records")).to_dict() quality_groups = quality_df.groupby("Road").apply(lambda x: x.to_dict("records")).to_dict() traffic_groups = traffic_df.groupby("Road").apply(lambda x: x.to_dict("records")).to_dict()
3. 生成细分路段并匹配属性
定义一个函数,专门处理单条道路的细分和属性匹配:
def process_single_road(road_id, pavement_segs, quality_segs, traffic_segs): # 收集这条道路的所有断点(From和To的所有值) all_nodes = set() for seg in pavement_segs: all_nodes.add(seg["From"]) all_nodes.add(seg["To"]) for seg in quality_segs: all_nodes.add(seg["From"]) all_nodes.add(seg["To"]) for seg in traffic_segs: all_nodes.add(seg["From"]) all_nodes.add(seg["To"]) # 把断点排序,生成连续的细分路段 sorted_nodes = sorted(all_nodes) segment_results = [] for i in range(len(sorted_nodes) - 1): seg_from = sorted_nodes[i] seg_to = sorted_nodes[i+1] # 匹配路面属性:找包含当前细分路段的原路面路段 pavement = next( s["Pavement"] for s in pavement_segs if s["From"] <= seg_from and s["To"] >= seg_to ) # 匹配质量属性 quality = next( s["Quality"] for s in quality_segs if s["From"] <= seg_from and s["To"] >= seg_to ) # 匹配交通量属性 traffic = next( s["Traffic"] for s in traffic_segs if s["From"] <= seg_from and s["To"] >= seg_to ) segment_results.append({ "Road": road_id, "From": seg_from, "To": seg_to, "Quality": quality, "Pavement": pavement, "Traffic": traffic }) return segment_results
4. 批量处理所有道路并输出结果
# 遍历所有道路,收集结果 final_results = [] for road in pavement_groups.keys(): # 获取当前道路的各类型路段数据 pavement_segs = pavement_groups[road] quality_segs = quality_groups.get(road, []) traffic_segs = traffic_groups.get(road, []) # 处理当前道路 road_segments = process_single_road(road, pavement_segs, quality_segs, traffic_segs) final_results.extend(road_segments) # 转换成DataFrame,还可以把小数转回逗号格式(如果需要) final_df = pd.DataFrame(final_results) final_df["From"] = final_df["From"].apply(lambda x: f"{x:.2f}".replace(".", ",")) final_df["To"] = final_df["To"].apply(lambda x: f"{x:.2f}".replace(".", ",")) # 输出到Excel final_df.to_excel("合并后细分路段表.xlsx", index=False)
为什么这个思路可行?
本质上是把所有的路段断点都整合起来,把道路拆分成没有重叠的最小连续单元,每个单元必然完全包含在原三个表的某一个路段区间内,所以只要通过区间判断就能准确匹配到对应的属性值。
这种方法比用SQL查询更直观,因为SQL处理区间嵌套和细分路段的逻辑会复杂很多,而Python的循环+匹配逻辑更清晰,也容易调试。
内容的提问来源于stack exchange,提问作者zofka
相关产品推荐
相关产品推荐

