Я собираюсь сделать это в ванильном Python, а не с помощью панд. По сути, вы хотите создать набор деревьев и затем пройти их от корневых узлов этих деревьев.
Допустим, вы уже проанализировали данные и можете начать с некоторого списка processes
изструктура List[Tuple[int, int]]
.
processes = [
(273500, 273500),
(20574624, 273500),
(2202652, 1879450),
(19933526, 1879450),
(18000796, 18352628),
(18352628, 19770000),
(1359996, 20574624),
(1879450, 20574624),
(18441258, 20574624),
(20637582, 20574624),
(20840426, 20574624),
(20844632, 20574624),
(20934910, 20574624),
(20965442, 20574624),
(21193122, 20574624),
(21194666, 21193122),
(19770000, 20574624),
(19681810, 18352628),
(19931554, 20574624),
(18382902, 1879450),
(19780666, 1879450),
(20631784, 20574624),
]
Мы можем представить все узлы в нашем дереве как Dict[int, List[int]]
родительских дочерних отношений. Следующий метод может быть вызван в кадре путем вызова sort_processes(df.values.tolist())
. Результат можно преобразовать обратно в панд, позвонив pandas.DataFrame(result, columns=['Child', 'Parent'])
:
from collections import defaultdict
from typing import Dict, List, Iterable, Tuple
def sort_processes(processes: List[Tuple[int, int]]) -> List[Tuple[int, int]]:
# initialize the nodes
nodes: Dict[int, List[int]] = defaultdict(list)
for child, parent in processes:
nodes[parent].append(child)
# walk and yield pairs
def walk_tree(parent: int) -> Iterable[Tuple[int, int]]:
for child in sorted(nodes[parent]):
yield (child, parent)
# avoid infinite loops
if parent != child:
yield from walk_tree(child)
# start at top level parents
parents = [parent for child, parent in processes if parent == child]
return list(
pair for parent in sorted(parents) for pair in walk_tree(parent)
)
Вызвав sort_processes(processes)
Возвращает:
[
(273500, 273500),
(20574624, 273500),
(1359996, 20574624),
(1879450, 20574624),
(2202652, 1879450),
(18382902, 1879450),
(19780666, 1879450),
(19933526, 1879450),
(18441258, 20574624),
(19770000, 20574624),
(18352628, 19770000),
(18000796, 18352628),
(19681810, 18352628),
(19931554, 20574624),
(20631784, 20574624),
(20637582, 20574624),
(20840426, 20574624),
(20844632, 20574624),
(20934910, 20574624),
(20965442, 20574624),
(21193122, 20574624),
(21194666, 21193122),
]