Вы могли бы сделать точечное отображение emp_id
на mgr_id
, а затем сделать рекурсивную функцию, такую как
idmap = dict(zip(df['emp_id'], df['mgr_id']))
def depth(id_):
if np.isnan(id_):
return 1
return depth(idmap[id_]) + 1
, чтобы вычислить глубину с учетом id
.Чтобы сделать его более эффективным (не повторяя расчеты для одного и того же id
), вы можете использовать памятку (обрабатывается @functools.lru_cache
декоратором ниже):
import numpy as np
import pandas as pd
import functools
nan = np.nan
df = pd.DataFrame({'emp_id': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'fn': ['Matthew', 'John', 'Chris', 'Sergey', 'Andrey', 'Karen', 'Tri', 'Drew', 'BD', 'Sreedhar'], 'ln': ['Reichek', 'Cottone', 'Winter', 'Bobkov', 'Botelli', 'Goetz', 'Pham', 'Thompson', 'Alabi', 'Kavali'], 'mgr_id': [nan, 3.0, 1.0, 2.0, 2.0, 7.0, 3.0, 7.0, 7.0, 7.0]})
def make_depth(df):
idmap = dict(zip(df['emp_id'], df['mgr_id']))
@functools.lru_cache()
def depth(id_):
if np.isnan(id_):
return 1
return depth(idmap[id_]) + 1
return depth
df['depth'] = df['mgr_id'].apply(make_depth(df))
print(df.sort_values(by='depth'))
выход
emp_id fn ln mgr_id depth
0 1 Matthew Reichek NaN 1
2 3 Chris Winter 1.0 2
1 2 John Cottone 3.0 3
6 7 Tri Pham 3.0 3
3 4 Sergey Bobkov 2.0 4
4 5 Andrey Botelli 2.0 4
5 6 Karen Goetz 7.0 4
7 8 Drew Thompson 7.0 4
8 9 BD Alabi 7.0 4
9 10 Sreedhar Kavali 7.0 4