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

如何从Pandas DataFrame中找出线路连接序列(Python3)

如何基于Pandas DataFrame中的起点终点列找出线路的连接序列?

问题场景

我在Pandas DataFrame里定义了多条线路,每条线路包含起点(from列)和终点(to列),这些线路是按顺序首尾连接的(比如示例里的line_a → line_b → line_c)。现在需要从from和to列自动识别出这个连接顺序,输出像['line_a', 'line_b', 'line_c']这样的字符串列表,实际应用里的点名可以是任意字符串,最终结果需要是List[str]格式。

示例DataFrame代码:

import pandas as pd
df = pd.DataFrame(
    {
        'from': ['p2', 'p3', 'p1'],
        'to': ['p3', 'p4', 'p2'],
    },
    index=['line_b', 'line_c', 'line_a'],
)

解决方案1:纯Pandas+字典映射(轻量无依赖)

这种方法不需要额外库,通过构建映射关系来遍历出连接序列,完美适配单链式的线路结构:

import pandas as pd

df = pd.DataFrame(
    {
        'from': ['p2', 'p3', 'p1'],
        'to': ['p3', 'p4', 'p2'],
    },
    index=['line_b', 'line_c', 'line_a'],
)

# 1. 构建两个关键映射字典
# 终点 → 对应的线路名(下一条线路的起点等于当前线路的终点)
to_to_line = df['to'].reset_index().set_index('to')['index'].to_dict()
# 起点 → 对应的线路名
from_to_line = df['from'].reset_index().set_index('from')['index'].to_dict()

# 2. 找到起始线路:起点不在任何线路的终点集合里的那条线路
start_point = set(df['from']) - set(df['to'])
start_line = from_to_line[start_point.pop()]

# 3. 遍历构建完整序列
sequence = [start_line]
current_end = df.loc[start_line, 'to']

# 顺着终点找下一条线路,直到没有后续为止
while current_end in to_to_line:
    next_line = to_to_line[current_end]
    sequence.append(next_line)
    current_end = df.loc[next_line, 'to']

print(sequence)  # 输出: ['line_a', 'line_b', 'line_c']

思路说明:

  • 先把每个终点和对应的线路、每个起点和对应的线路做映射,方便后续快速查找;
  • 链式结构的起始线路有个明显特征:它的起点不会是任何其他线路的终点,通过集合差集就能快速定位;
  • 之后只需要顺着当前线路的终点,去找到下一条以该终点为起点的线路,循环往复直到没有后续线路即可。

解决方案2:用NetworkX处理(适合复杂扩展)

如果之后可能遇到更复杂的线路结构(比如分支,当然当前问题是单链),可以用NetworkX这个图论库来处理,代码可读性更强,扩展性也更好:

import pandas as pd
import networkx as nx

df = pd.DataFrame(
    {
        'from': ['p2', 'p3', 'p1'],
        'to': ['p3', 'p4', 'p2'],
    },
    index=['line_b', 'line_c', 'line_a'],
)

# 1. 构建有向图,每条边携带着对应的线路名
G = nx.DiGraph()
for line_name, row in df.iterrows():
    G.add_edge(row['from'], row['to'], line=line_name)

# 2. 找到起始节点(入度为0,没有其他节点指向它)和结束节点(出度为0,不指向其他节点)
start_node = [node for node, degree in G.in_degree() if degree == 0][0]
end_node = [node for node, degree in G.out_degree() if degree == 0][0]

# 3. 获取路径上的所有边,提取对应的线路名
path_nodes = nx.shortest_path(G, start_node, end_node)
sequence = []
for i in range(len(path_nodes) - 1):
    # 从边的属性中取出线路名
    sequence.append(G[path_nodes[i]][path_nodes[i+1]]['line'])

print(sequence)  # 输出: ['line_a', 'line_b', 'line_c']

思路说明:

  • 把每个点名当成图的节点,每条线路当成连接两个节点的有向边,同时把线路名存在边的属性里;
  • 单链结构的起始节点入度为0(没有其他边指向它),结束节点出度为0;
  • 找到两个节点之间的最短路径(因为是单链,只有一条路径),然后依次提取路径上每条边的线路名,就是最终的连接序列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 18:42:31