У меня есть набор данных из двух столбцов, изображающий множественные отношения между родителями и родителями, которые образуют большое дерево. Я хотел бы использовать это для создания обновленного списка каждого потомка для каждого node.
Исходный ввод:
child parent
1 2010 1000
7 2100 1000
5 2110 1000
3 3000 2110
2 3011 2010
4 3033 2100
0 3102 2010
6 3111 2110
Графическое описание отношений:
Ожидаемый результат:
descendant ancestor
0 2010 1000
1 2100 1000
2 2110 1000
3 3000 1000
4 3011 1000
5 3033 1000
6 3102 1000
7 3111 1000
8 3011 2010
9 3102 2010
10 3033 2100
11 3000 2110
12 3111 2110
Первоначально я решил использовать рекурсивное решение с DataFrames. Он работает по назначению, но Pandas ужасно неэффективен. Мои исследования привели меня к мысли, что реализация с использованием массивов NumPy (или других простых структур данных) будет намного быстрее на больших наборах данных (из 10 тысяч записей).
Решение с использованием фреймов данных:
import pandas as pd
df = pd.DataFrame(
{
'child': [3102, 2010, 3011, 3000, 3033, 2110, 3111, 2100],
'parent': [2010, 1000, 2010, 2110, 2100, 1000, 2110, 1000]
}, columns=['child', 'parent']
)
def get_ancestry_dataframe_flat(df):
def get_child_list(parent_id):
list_of_children = list()
list_of_children.append(df[df['parent'] == parent_id]['child'].values)
for i, r in df[df['parent'] == parent_id].iterrows():
if r['child'] != parent_id:
list_of_children.append(get_child_list(r['child']))
# flatten list
list_of_children = [item for sublist in list_of_children for item in sublist]
return list_of_children
new_df = pd.DataFrame(columns=['descendant', 'ancestor']).astype(int)
for index, row in df.iterrows():
temp_df = pd.DataFrame(columns=['descendant', 'ancestor'])
temp_df['descendant'] = pd.Series(get_child_list(row['parent']))
temp_df['ancestor'] = row['parent']
new_df = new_df.append(temp_df)
new_df = new_df\
.drop_duplicates()\
.sort_values(['ancestor', 'descendant'])\
.reset_index(drop=True)
return new_df
Поскольку использование Pandas DataFrames таким образом очень неэффективно для больших наборов данных, Мне нужно улучшить производительность этой операции. Я понимаю, что это можно сделать, используя более эффективные данные структуры, более подходящие для циклирования и рекурсии. Я хочу выполнить эту самую операцию наиболее эффективным способом.
В частности, я прошу оптимизировать скорость.