从Pandas数据框中查找全层次数据的节点深度
我有一个Pandas的数据框,里面有一些层级数据,也就是有上下级关系的数据。
data = pd.DataFrame({
"manager_id": ["A", "A", "B", "A", "C", "A", "B", "F"],
"employee_id": ["B", "C", "C", "D", "E", "E", "E", "G"]
} )
这些数据包含了每个经理的所有下属关系。比如说,对于每个经理的ID(例如"A"),员工的ID包括了直接由经理"A"管理的员工(例如"B"),以及由员工"B"管理的员工(例如"C"和"D")。我已经找到了一种方法,可以用networkx库从这些数据创建一个图形(如何从Pandas数据框生成完整层级数据的图形?)。但是我想知道,如何在这个数据中添加一列,计算每个经理和员工在图中的深度呢?
期望的输出如下:
manager_id employee_id depth
0 A B 1
1 A C 2
2 B C 1
3 A D 1
4 C E 1
5 A E 3
6 B E 2
7 F G 1
1 个回答
1
在我之前的回答中提到过,你可以通过topological_generations
来获取节点的绝对深度。因为你想要的是相对深度,所以可以用employee_id
的深度减去manager_id
的深度(这两个深度都可以通过order
和map
来获取):
import networkx as nx
# create directed graph
G = nx.from_pandas_edgelist(data, source='manager_id', target='employee_id',
create_using=nx.DiGraph)
# get node generation
order = {n: i for i, l in enumerate(nx.topological_generations(G)) for n in l}
# {'A': 0, 'F': 0, 'B': 1, 'D': 1, 'G': 1, 'C': 2, 'E': 3}
# map generation on both source/target
# compute difference to get the relative depth
data['depth'] = (data['employee_id'].map(order)
.sub(data['manager_id'].map(order))
)
输出结果:
manager_id employee_id depth
0 A B 1
1 A C 2
2 B C 1
3 A D 1
4 C E 1
5 A E 3
6 B E 2
7 F G 1
中间结果:
manager_id employee_id manager_id_depth employee_id_depth depth
0 A B 0 1 1
1 A C 0 2 2
2 B C 1 2 1
3 A D 0 1 1
4 C E 2 3 1
5 A E 0 3 3
6 B E 1 3 2
7 F G 0 1 1
展示了节点的绝对深度以及相对深度的计算(子节点深度 - 父节点深度)的图: