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

Python中map函数替代方案及报表计数全零问题排查

问题分析与解决

核心问题原因

你的代码中df['ID'].map(counts)是错误的,因为counts的索引是Manager_Pos_Num(如1111、2222),而df['ID']的值是员工编号(如101、103),两者的键完全不匹配,导致映射后所有值都是NaN,经过fillna(0)后就全变成0了——和map函数本身无关,是映射的键选错了。

正确实现代码

你需要先统计每个管理者+对应职位编号的下属数量,再将该数量关联到对应的管理者行上,同时保留普通员工的行(Reports为0):

import pandas as pd

# 构造样本数据
data = {
    'ID': [101, 102, 103, 104, 105, 106],
    'Manager_ID': [103, 103, 106, 103, 106, None],
    'Manger_Pos_Num': [1111, 1111, 2222, 3333, 2222, None]
}
df = pd.DataFrame(data)
# 修正列名拼写错误:Manger_Pos_Num → Manager_Pos_Num
df.rename(columns={'Manger_Pos_Num': 'Manager_Pos_Num'}, inplace=True)

# 步骤1:统计每个管理者+职位的下属数量
manager_reports = df.dropna(subset=['Manager_Pos_Num']).groupby(['Manager_ID', 'Manager_Pos_Num'])['ID'].nunique().reset_index(name='Reports')

# 步骤2:合并到原数据,生成最终结果
result = df[['ID']].merge(manager_reports, left_on='ID', right_on='Manager_ID', how='left')
result['Reports'] = result['Reports'].fillna(0).astype(int)
result = result[['ID', 'Reports']]

print(result)

执行后输出与你的期望一致:

ID  Reports
0  101        0
1  102        0
2  103        2
3  103        1
4  105        0
5  106        2

map函数的替代方案

1. 使用DataFrame.merge()(推荐)

如上面的代码所示,merge是处理这类关联统计最常用的方法,逻辑清晰且效率高,适合大数据集。

2. 使用apply()(适合小数据集)

通过自定义函数对每个ID统计下属数量,适合数据量不大的场景:

def get_reports_count(id_val):
    # 筛选当前ID作为管理者的所有下属,按职位分组统计数量
    pos_counts = df[df['Manager_ID'] == id_val].groupby('Manager_Pos_Num')['ID'].nunique()
    return pos_counts.tolist() if not pos_counts.empty else [0]

# 扩展行生成结果
ids = []
reports = []
for _, row in df.iterrows():
    counts = get_reports_count(row['ID'])
    for cnt in counts:
        ids.append(row['ID'])
        reports.append(cnt)

result = pd.DataFrame({'ID': ids, 'Reports': reports})

3. 使用Series.replace()

如果需要直接对字段进行映射替换,可以先建立职位到数量的映射,再关联到管理者:

# 先统计职位对应的下属数量
pos_counts = df.dropna(subset=['Manager_Pos_Num']).groupby('Manager_Pos_Num')['ID'].nunique()
# 建立管理者ID到对应职位的映射
manager_pos_map = df.dropna(subset=['Manager_Pos_Num']).groupby('Manager_ID')['Manager_Pos_Num'].unique()

# 生成结果
ids = []
reports = []
for id_val in df['ID']:
    if id_val in manager_pos_map.index:
        for pos in manager_pos_map[id_val]:
            ids.append(id_val)
            reports.append(pos_counts[pos])
    else:
        ids.append(id_val)
        reports.append(0)

result = pd.DataFrame({'ID': ids, 'Reports': reports})

内容的提问来源于stack exchange,提问作者Coding_Nubie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:52:57