Рекурсивный поиск связанных компонентов во фрейме данных

Рассмотрим следующий фрейм данных:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {
        "main": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        "component": [
            [1, 2],
            [np.nan],
            [3, 8],
            [np.nan],
            [1, 5, 6],
            [np.nan],
            [7],
            [np.nan],
            [9, 10],
            [np.nan],
            [np.nan],
        ],
    }
)

Столбец main представляет определенный подход. Каждый подход состоит из компонентов. Сам компонент также может быть подходом и тогда называется подподходом.

Я хочу найти все связанные подподходы/компоненты для определенного подхода.

Предположим, например, что я хочу найти все связанные под-подходы/компоненты для основного подхода «0». Тогда мой желаемый результат будет выглядеть так:

target = pd.DataFrame({
    "main": [0, 0, 2, 2, 8, 8],
    "component": [1, 2, 3, 8, 9, 10]
})

В идеале я хочу иметь возможность просто выбрать подход, а затем получить все дополнительные соединения. Я убежден, что для этого есть разумный подход с помощью networkx. Любая подсказка приветствуется.

В конечном итоге я хочу создать график, который выглядит примерно так (для подхода 0):

Дополнительная информация:

Вы можете разбить фрейм данных, а затем удалить все компоненты из столбца main (компоненты — это подходы, которые не имеют компонентов).

df_exploded = df.explode(column = "component").dropna(subset = "component")

График можно построить следующим образом:

import networkx as nx
import graphviz

G = nx.Graph()
G.add_edges_from([(i, j) for i, j in target.values])

graph_attr = dict(rankdir = "LR", nodesep = "0.2")
g = graphviz.Digraph(graph_attr=graph_attr)

for k, v in G.nodes.items():
    g.node(str(k), shape = "box", style = "filled", height = "0.35")

for n1, n2 in G.edges:
    g.edge(str(n2), str(n1))

g

Каков ожидаемый результат?

Corralien 17.02.2023 12:08

@Corralien, ожидаемым результатом будет фрейм данных с именем target во втором фрейме ячейки для подхода 0. В конце концов, ожидаемый результат зависит от номера подхода, который я хочу указать. Но можно предположить, что здесь номер подхода равен 0.

ko3 17.02.2023 12:19

Хорошо. Извините, я неправильно прочитал. Вы можете использовать dfs_edges для решения вашей проблемы. Вы можете проверить мой ответ ниже.

Corralien 17.02.2023 12:28
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
1
3
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете использовать nx.dfs_edges

edges = df.explode(column='component').dropna(subset='component')

G = nx.from_pandas_edgelist(edges, source='main', target='component', create_using=nx.DiGraph)

target = pd.DataFrame(nx.dfs_edges(G, 0), columns=['main', 'component'])

Выход:

>>> target
   main  component
0     0          1
1     0          2
2     2          3
3     2          8
4     8          9
5     8         10

Чтобы извлечь подграф, используйте:

H = G.edge_subgraph(nx.dfs_edges(G, 0))

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