Рассмотрим следующий фрейм данных:
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, ожидаемым результатом будет фрейм данных с именем target во втором фрейме ячейки для подхода 0. В конце концов, ожидаемый результат зависит от номера подхода, который я хочу указать. Но можно предположить, что здесь номер подхода равен 0.
Хорошо. Извините, я неправильно прочитал. Вы можете использовать dfs_edges для решения вашей проблемы. Вы можете проверить мой ответ ниже.
Вы можете использовать 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))
Каков ожидаемый результат?