Получить все нисходящие ноды для всех узлов дерева, представленных пандой DataFrame - PullRequest
0 голосов
/ 30 января 2019

Полное раскрытие: я задал похожий вопрос в Code Review , но не получил никакой обратной связи с использованием панд, и я хотел быть более конкретным.

У меня есть DataFrameудерживая «плоскую» таблицу ребер дерева (НЕ двоичную, но узел не может иметь двух родителей), ребра ~ 1M, см. пример:

import pandas as pd

nodes_df = pd.DataFrame({'node_id': [1,2,3,4,5,6,7,8,9,10], 'parent_id': [0,1,1,2,2,3,4,5,6,6]})
nodes_df
   node_id  parent_id
0        1          0
1        2          1
2        3          1
3        4          2
4        5          2
5        6          3
6        7          4
7        8          5
8        9          6
9       10          6

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

Я хочу, чтобы для каждого node_id был получен набор всех узлов-потомков (включая самого себя, распространяемых до тех пор, пока не уйдет), искорость имеет решающее значение.Я говорю «установить», потому что это то, что я делаю в настоящее время (см. Ниже).Но даже более длинная таблица, полученная в результате манипуляций с пандами (node_id, lowerndant_node_id), тоже подойдет.

В настоящее время я создаю словарь из node_id для набора всех его потомков, например:

from collections import defaultdict

node_descendants = defaultdict(set)
node_descendants[0] = set([0])
for _, node_id, parent_id in nodes_df[::-1].itertuples():
    node_descendants[node_id].add(node_id)
    node_descendants[parent_id].update(node_descendants[node_id])

node_descendants
defaultdict(<class 'set'>, {0: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 10: {10}, 6: {9, 10, 6}, 9: {9}, 8: {8}, 5: {8, 5}, 7: {7}, 4: {4, 7}, 3: {9, 10, 3, 6}, 2: {2, 4, 5, 7, 8}, 1: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}})

Есть ли какой-нибудь способ, которым я мог бы использовать силу панд для этого, с join s и groupby s?Желательно намного быстрее (помните, у меня ~ 1M ребер или узлов, а не 10)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...