Кадр данных со столбцами FROM и TO. Неупорядоченный, получите правильные комбинации

df = pd.DataFrame({
    'from': ['Start', '21', '73', 'Start', '55', '1', '2', '3'],
    'to': ['21', '73', '55', '1', '54', '2', '3', '4']
})
от к 0 Начинать 21 1 21 73 2 73 55 3 Начинать 1 4 55 54 5 1 2 6 2 3 7 3 4

желаемый результат

[['Start', '21', '73', '55', '54'], ['Start', '1', '2', '3', '4']]

[РЕДАКТИРОВАТЬ]

Итак, вы начинаете с «Начало» в столбце «От» и находите «21» в столбце «До» этой строки. Теперь вам нужно найти «21» в столбце «от» и перейти к «73». Затем повторяйте шаги, пока в поле «from» ничего не будет найдено, что указывает на то, что соединение установлено.

Связи ацикличны и неразветвлены.

[КОНЕЦ РЕДАКТИРОВАНИЯ]

строки не обязательно должны быть в правильном порядке, как в случае 55, 54.

Этот вопрос нуждается в более ясной логике. Будет множество случаев неупорядоченности, и, пожалуйста, приложите логику того, как с этим следует обращаться. Было бы неплохо привести и другой пример.

Panda Kim 05.07.2024 11:02

Вам нужен список списков в качестве вывода?

mozway 05.07.2024 11:09

@mozway да, список всех соединений в фрейме данных. В примере их всего два.

Paul 05.07.2024 11:10

Понятно, тогда можно считать это проблемой графа и использовать networkx (см. ниже)

mozway 05.07.2024 11:13

@PandaKim, что непонятно? вы начинаете с «Начала», затем получаете 21 в «до», затем возвращаетесь к столбцу «от», находите 21 и получаете соответствующее 73 и т. д. то же самое для другого «Начала».

mozway 05.07.2024 11:18

@Пол, возможно, ты захочешь разобрать свой полный пример, чтобы продемонстрировать логику (как я это сделал в комментарии выше).

mozway 05.07.2024 11:20

@mozway Это также имеет смысл, поскольку это дает общий результат.

Panda Kim 05.07.2024 11:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это проблема с графами, для ее решения вы можете использовать networkx.

Сначала дедуплицируйте начало, затем создайте ориентированный граф, получите слабо_подключенные_компоненты , затем dag_longest_path :

import networkx as nx

# deduplicate the Start
m = df['from'].eq('Start')
from_ = df['from'].mask(m, 'Start'+m.cumsum().astype(str))
# ['Start1', '21', '73', 'Start2', '55', '1', '2', '3']

# create a graph
G = nx.from_edgelist(zip(from_, df['to']),
                     create_using=nx.DiGraph)

# get isolated paths
out = [nx.dag_longest_path(G.subgraph(c))
       for c in nx.weakly_connected_components(G)]

Выход:

[['Start1', '21', '73', '55', '54'], ['Start2', '1', '2', '3', '4']]

График:

Вы также можете использовать функцию Python, чтобы вручную следовать по пути для каждого запуска:

def find_path(df, frm='from', to='to'):
    # create a Series with from as index, to as values
    s = df.set_index(frm)[to]
    out = []
    # for each Start, follow the path
    for val in s[s.index=='Start']:
        out.append(['Start', val])
        while (val := s.get(val)) is not None:
            out[-1].append(val)
    return out

out = find_path(df)
# [['Start', '21', '73', '55', '54'], ['Start', '1', '2', '3', '4']]

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

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

mozway 05.07.2024 11:38

Под «неупорядоченным» я предполагаю, что OP имел в виду, что выходные данные не обязательно содержат узлы в числовом порядке, но они должны быть упорядочены по пути.

mozway 05.07.2024 11:40

Вы правы, это должно быть четко указано. @Пол, не могли бы вы подтвердить в вопросе, что граф ациклический и неразветвленный?

mozway 05.07.2024 11:54

Другие вопросы по теме