Python Pandas 获取到高层管理的层级路径

1 投票
1 回答
60 浏览
提问于 2025-04-11 22:38

我有一个下面的 pandas 数据框(DF)

这里插入图片描述

创建这个数据框的步骤

data=[['1','0','0','0','0'],['2','1','1','0','0|0'],['3','1','1','1','0|1'],['4','2','2','0','0|0|0'],['5','2','2','1','0|0|1'],['6','2','2','2','0|0|2'],['7','3','2','0','0|1|0'],['8','3','2','1','0|1|1'],['9','3','2','2','0|1|2'],['10','3','2','3','0|1|3'],['11','4','3','0','0|0|0|0'],['12','4','3','1','0|0|0|1'],['13','10','3','0','0|1|3|0']]
df = pd.DataFrame(data, columns=['eid','m_eid','level','path_variable','complete_path'])
df=df.drop('complete_path',axis=1)

这里:

eid = 员工编号

m_eid = 经理编号

level = 在组织中的级别(0 是最高的老板)

path_variable = 根据员工的级别分配的递增编号,这个编号会根据每个经理重置(例如:eid[4,5,6,7,8,9,10] 都属于同一级别 2,但 eid[4,5,6] 有相同的经理(m_eid=2),所以他们的 path_variable 是 0,1,2,而 eid[7,8,9,10] 有不同的经理(m_eid=3),所以 path_variable 从 0 开始重新计数)

我想创建一个新列,显示每个 eid 从最底层到 0 级别的完整路径。就像下面这样:

输出

完整路径是从底层到顶层(最高老板)的 path_variable 的连接。

这就像是从根节点到边缘节点的路径。例如,假设我们看 eid 10

这里插入图片描述

在直接经理之间可能会有级别跳跃。我想避免使用 iterrows(),因为性能方面的限制。

1 个回答

3

如果我理解得没错,你可以使用networkx来构建一个有向图,然后找到每个节点到'0'shortest_path,接着用这个结果来映射path_variable

import networkx as nx

G = nx.from_pandas_edgelist(df, source='m_eid', target='eid',
                            create_using=nx.DiGraph)

s = df.set_index('eid')['path_variable']

mapper = {n: '|'.join(s.get(x, '') for x in 
                      nx.shortest_path(G, source='0',
                                       target=n)[1:])
          for n in df['eid'].unique()
         }
df['complete_path'] = df['eid'].map(mapper)

输出结果:

   eid m_eid level path_variable complete_path
0    1     0     0             0             0
1    2     1     1             0           0|0
2    3     1     1             1           0|1
3    4     2     2             0         0|0|0
4    5     2     2             1         0|0|1
5    6     2     2             2         0|0|2
6    7     3     2             0         0|1|0
7    8     3     2             1         0|1|1
8    9     3     2             2         0|1|2
9   10     3     2             3         0|1|3
10  11     4     3             0       0|0|0|0
11  12     4     3             1       0|0|0|1
12  13    10     3             0       0|1|3|0

图示:

组织图,networkx图形

如果你已经在eid中有唯一的值,你可以省略映射器,直接使用:

df['complete_path'] = ['|'.join(s.get(x, '') for x in 
                       nx.shortest_path(G, source=n,
                                        target='0')[-2::-1])
                       for n in df['eid']]

为了让理解更简单,这里有一个更经典的路径,显示的是节点的ID(不是path_variables):

mapper = {n: '|'.join(nx.shortest_path(G, source='0',
                                       target=n)[1:])
          for n in df['eid'].unique()
         }
df['complete_path'] = df['eid'].map(mapper)

输出结果:

   eid m_eid level path_variable complete_path
0    1     0     0             0             1
1    2     1     1             0           1|2
2    3     1     1             1           1|3
3    4     2     2             0         1|2|4
4    5     2     2             1         1|2|5
5    6     2     2             2         1|2|6
6    7     3     2             0         1|3|7
7    8     3     2             1         1|3|8
8    9     3     2             2         1|3|9
9   10     3     2             3        1|3|10
10  11     4     3             0      1|2|4|11
11  12     4     3             1      1|2|4|12
12  13    10     3             0     1|3|10|13

撰写回答