Наиболее естественным здесь является использование древовидной структуры данных, которая будет иметь линейное время запроса.Хотя я удивлен, что ваш подход был таким медленным, так как 3000 точек данных невелики.
import pandas as pd
from treelib import Tree
df = pd.DataFrame(
{
"parent_name":
["Car", "Tyre", "Tyre", "Rubber", "Nylon", "Nylon", "Trees", "Trees"],
"child_name": ["Tyre", "Rubber", "Nylon", "Trees", "Chemicals", "Man-made", "Leaves", "Stems"]
}
)
tree = Tree()
tree.create_node(df["parent_name"][0], df["parent_name"][0]) # root
for i, row in df.iterrows():
tree.create_node(row["child_name"], row["child_name"], parent=row["parent_name"])
tree.show()
def find_parents(child_name):
child = tree[child_name]
parent_names = []
while child.bpointer is not None:
parent = tree[child.bpointer]
parent_names.append(parent.identifier)
child = parent
return parent_names
print(find_parents("Trees"))
df["list_of_parents"] = df["child_name"].apply(find_parents)
Примечание: если вы измените фрейм данных, вам придется воссоздать дерево перед повторным вызовом функции "find_parents",Если вы регулярно изменяете фрейм данных, вы можете восстановить дерево внутри функции find_parents.
РЕДАКТИРОВАТЬ: Привет @AkshayKannan, извините за поздний ответ.Поскольку некоторые узлы могут иметь несколько родителей, правильная структура, которую следует здесь использовать, - это не дерево, а ориентированный ациклический граф (DAG).Следующее должно работать (я добавил строку («Нейлон», «Листья»), чтобы проверить случай с несколькими родителями)
import pandas as pd
import networkx as nx
df = pd.DataFrame(
{
"parent_name":
["Car", "Tyre", "Tyre", "Rubber", "Nylon", "Nylon", "Trees", "Trees", "Nylon"],
"child_name": ["Tyre", "Rubber", "Nylon", "Trees", "Chemicals", "Man-made", "Leaves", "Stems", "Leaves"]
}
)
G = nx.DiGraph()
for i, row in df.iterrows():
G.add_edge(row["child_name"], row["parent_name"])
nx.draw(G, with_labels=True)
def find_parents(child_name):
return list(nx.descendants(G, child_name))
print(find_parents("Car"))
print(find_parents("Chemicals"))
print(find_parents("Leaves"))