You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效统计DataFrame中指定员工的下属人数(含多层级)

高效统计多层级员工下属人数方案

针对大数据量、多层级的员工-上级DataFrame,原始字典循环效率低下的问题,推荐两种高效方案:

方案一:用NetworkX构建有向图(推荐大数据量场景)

NetworkX内置了优化的图遍历算法,能快速获取节点的所有后代(含间接下属),时间复杂度接近O(n+m)(n为员工数,m为上下级关系数),远优于嵌套循环的O(n²)。

代码示例

import networkx as nx
import pandas as pd

# 示例DataFrame(替换为你的真实数据)
df = pd.DataFrame({
    'Employee': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'Manager': [None, 'A', 'A', 'A', 'A', 'B', 'B', 'C', 'C']
})

# 1. 构建有向图:上级→下属的边
G = nx.DiGraph()
G.add_nodes_from(df['Employee'])
# 过滤无上级的顶层节点,添加合法的上下级边
valid_edges = df.dropna(subset=['Manager'])[['Manager', 'Employee']].values.tolist()
G.add_edges_from(valid_edges)

# 2. 统计每个员工的下属数及具体名单
subordinate_stats = {}
for emp in df['Employee']:
    descendants = list(nx.descendants(G, emp))
    subordinate_stats[emp] = {
        'count': len(descendants),
        'subordinates': descendants
    }

# 3. 输出结果(按需求格式化)
for emp, stats in subordinate_stats.items():
    if stats['count'] == 0:
        print(f"{emp}无下属")
    else:
        print(f"{emp}有{stats['count']}名下属({', '.join(stats['subordinates'])})")

优势

  • 底层算法优化,处理十万级以上数据依然高效
  • 一行代码nx.descendants即可获取所有间接下属,无需手动实现遍历逻辑
  • 可快速扩展其他需求(比如检测层级循环、生成层级路径等)

方案二:手动实现广度优先遍历(BFS,无第三方依赖)

如果不想引入NetworkX依赖,可预先构建「上级→直接下属」的映射字典,再用迭代式BFS遍历所有层级,避免递归栈溢出,同时效率远高于原始循环。

代码示例

import pandas as pd

# 示例DataFrame(替换为你的真实数据)
df = pd.DataFrame({
    'Employee': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'Manager': [None, 'A', 'A', 'A', 'A', 'B', 'B', 'C', 'C']
})

# 1. 构建上级到直接下属的映射字典
manager_to_direct_subs = df.groupby('Manager')['Employee'].apply(list).to_dict()

# 2. 遍历每个员工,用BFS统计所有下属(含间接)
subordinate_stats = {}
for emp in df['Employee']:
    total = 0
    subs_list = []
    queue = manager_to_direct_subs.get(emp, []).copy()
    
    total += len(queue)
    subs_list.extend(queue)
    
    while queue:
        current_sub = queue.pop(0)
        # 获取当前下属的直接下属
        next_level_subs = manager_to_direct_subs.get(current_sub, [])
        total += len(next_level_subs)
        subs_list.extend(next_level_subs)
        queue.extend(next_level_subs)
    
    subordinate_stats[emp] = {
        'count': total,
        'subordinates': subs_list
    }

# 3. 输出结果
for emp, stats in subordinate_stats.items():
    if stats['count'] == 0:
        print(f"{emp}无下属")
    else:
        print(f"{emp}有{stats['count']}名下属({', '.join(stats['subordinates'])})")

优势

  • 无需额外安装库,代码轻量
  • 迭代式BFS避免了递归深度限制,适合极多层级的场景
  • 预先构建映射字典,避免重复遍历整个DataFrame,效率提升明显

注意事项

  1. 层级循环处理:如果数据存在循环(如A是B的上级,B是A的上级),两种方案都会陷入死循环。可先通过nx.is_directed_acyclic_graph(G)(NetworkX方案)或手动检测的方式清理数据。
  2. 顶层节点:确保处理Manager为None的顶层员工,避免遗漏统计。

内容的提问来源于stack exchange,提问作者Bruno Ramos Martins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:45:33