如何基于行间连续性条件聚合Pandas道路路段DataFrame?
连续同类型道路路段聚合解决方案
实现逻辑
要仅聚合连续且路段类型相同的路段,核心是先为每个连续同类型路段组生成唯一标识:
- 当当前路段的起始里程(PRIM_BMP)不等于前一段的结束里程(PRIM_EMP),视为非连续;
- 当当前路段类型(SEGMENT_TYPE)与前一段不同,视为类型变化;
- 非连续或类型变化时,标记为新组起点,通过累积求和生成组ID,再按组ID聚合。
代码实现
1. 构造示例数据
import pandas as pd # 还原提供的道路路段数据 data = [ ["0001A", 0, 0.147, 0.147, 4850943, 0, 2019, "Line"], ["0001A", 0.147, 0.183, 0.036, 4850943, 0, 2019, "Line"], ["0001A", 0.183, 0.24, 0.057, 4850943, 0, 2019, "Arc left"], ["0001A", 0.24, 0.251, 0.011, 4850945, 0, 2019, "Arc left"], ["0001A", 0.251, 0.27, 0.019, 4850945, 0, 2019, "Arc left"], ["0001A", 0.27, 0.295, 0.025, 4048920, 0, 2019, "Arc left"], ["0001A", 0.295, 0.31, 0.015, 4048920, 0, 2019, "Line"], ["0001A", 0.31, 0.36, 0.05, 4048921, 0, 2019, "Line"], ["0001A", 0.36, 0.363, 0.003, 4048779, 0, 2019, "Line"], ["0001A", 0.363, 0.437, 0.074, 4048779, 0, 2019, "Arc left"], ["0001A", 0.437, 0.483, 0.046, 4048779, 0, 2019, "Arc right"], ["0001A", 0.483, 0.568, 0.085, 4048779, 0, 2019, "Arc right"], ["0001A", 0.568, 0.6, 0.032, 4048779, 0, 2019, "Line"], ] df = pd.DataFrame( data, columns=["PRIRTECODE", "PRIM_BMP", "PRIM_EMP", "SEGMENT_LENGTH", "ELEMENT_ID", "RAMP", "CURVE_YEAR", "SEGMENT_TYPE"] )
2. 生成分组标识
# 判断当前路段是否与前一段连续 df["is_continuous"] = df["PRIM_BMP"] == df["PRIM_EMP"].shift(1) # 判断当前路段类型是否与前一段一致 df["type_match"] = df["SEGMENT_TYPE"] == df["SEGMENT_TYPE"].shift(1) # 生成组ID:非连续或类型变化时启动新组,累积求和 df["group_id"] = (~(df["is_continuous"] & df["type_match"])).cumsum()
3. 按组聚合
# 按组ID聚合,保留所需字段 agg_result = df.groupby("group_id").agg( PRIRTECODE=("PRIRTECODE", "first"), PRIM_BMP=("PRIM_BMP", "min"), PRIM_EMP=("PRIM_EMP", "max"), SEGMENT_LENGTH=("SEGMENT_LENGTH", "sum"), RAMP=("RAMP", "first"), CURVE_YEAR=("CURVE_YEAR", "first"), SEGMENT_TYPE=("SEGMENT_TYPE", "first") ).reset_index(drop=True)
4. 输出结果
print(agg_result)
执行后得到的聚合结果:
| PRIRTECODE | PRIM_BMP | PRIM_EMP | SEGMENT_LENGTH | RAMP | CURVE_YEAR | SEGMENT_TYPE |
|---|---|---|---|---|---|---|
| 0001A | 0.000 | 0.183 | 0.183 | 0 | 2019 | Line |
| 0001A | 0.183 | 0.295 | 0.112 | 0 | 2019 | Arc left |
| 0001A | 0.295 | 0.363 | 0.068 | 0 | 2019 | Line |
| 0001A | 0.363 | 0.437 | 0.074 | 0 | 2019 | Arc left |
| 0001A | 0.437 | 0.568 | 0.131 | 0 | 2019 | Arc right |
| 0001A | 0.568 | 0.600 | 0.032 | 0 | 2019 | Line |
(注:你提供的期望结果中合并了Arc left和Arc right段,但根据原始数据,这两段类型不同,因此实际聚合会分开。若需调整类型合并规则,可修改type_match的判断逻辑。)
内容的提问来源于stack exchange,提问作者Jhan
相关产品推荐
相关产品推荐

