Нахождение порядка начальной и конечной точек дороги на основе ее сегментов

#python #sql #pandas #loops

Вопрос:

У меня есть несколько тысяч дорог, каждая из которых состоит из одного или нескольких сегментов. Для каждого сегмента существует начальный и конечный узлы. Как мне их отсортировать, чтобы я мог получить начальный и конечный узлы дороги? Пример данных об одной дороге приведен на рисунке. Таблица Образцов

После того, как я узнаю начальный и конечный узлы дороги, я хочу применить эту информацию к каждому участку дороги, чтобы создать следующую таблицу.

Ожидаемый Результат

 
import pandas as pd

data = [['Road_id','Segment_id','Start_node','End_node'], [1,8285,4740,4741], [1,8509,4741,5144], [1,8437, 5016,5017], [1,8447, 5031, 5016], [1, 8520, 5144,5168], [1,9104,5168,4785],[1,8550,5017,4740]]

df = pd.DataFrame(data[1:], columns = data[0]) 

 

Комментарии:

1. Это называется «топологической сортировкой». По сути, вы составляете график узлов и ищете узлы, у которых нет предшественника или преемника. Панды не помогут вам в этой задаче; с таким же успехом вы можете хранить данные в списках Python.

Ответ №1:

Возможно, это даст вам толчок. Это выполняет топологическую сортировку и выводит сегменты по порядку. Вам придется расширить это, чтобы иметь дело с несколькими дорогами.

 data = [
    ['Road_id','Segment_id','Start_node','End_node'], 
    [1,8285,4740,4741],
    [1,8509,4741,5144],
    [1,8437,5016,5017],
    [1,8447,5031,5016],
    [1,8520,5144,5168],
    [1,9104,5168,4785],
    [1,8550,5017,4740]
]

# Reorganize the data a bit.

rows = {}
nexts = {}
starts = set()
ends = set()
for row in data:
    if isinstance(row[0],str):
        title = row
        continue
    rows[row[2]] = row
    nexts[row[2]]=row[3]
    starts.add(row[2])
    ends.add(row[3])

# Find the start without an end, and the end without a start.

start = (starts-ends).pop()
end = (ends-starts).pop()

# Go print out the rows along this route.

node = start
while node in nexts:
    print(rows[node])
    node = nexts[node]
 

Выход:

 (1, 8447, 5031, 5016)
(1, 8437, 5016, 5017)
(1, 8550, 5017, 4740)
(1, 8285, 4740, 4741)
(1, 8509, 4741, 5144)
(1, 8520, 5144, 5168)
(1, 9104, 5168, 4785)