
本文介绍如何基于用户列表(如离职人员)从dataframe中精准剔除所有由这些用户执行过的任务类型,仅保留完全由在职人员独立完成的任务类型。
本文介绍如何基于用户列表(如离职人员)从dataframe中精准剔除所有由这些用户执行过的任务类型,仅保留完全由在职人员独立完成的任务类型。
在实际数据分析中,常需识别“仅由特定群体执行”的业务行为——例如,找出从未被离职员工触碰过的任务类型(task type),以评估岗位职责的独占性或交接风险。关键在于:不是简单过滤掉离职员工的记录,而是排除所有曾被离职员工执行过的任务类型,哪怕该任务也由在职员工完成过。
以下为完整实现逻辑与代码示例:
✅ 正确思路:两步法(推荐)
- 识别离职人员执行过的全部任务类型(去重);
- 从原始数据中排除这些任务类型的所有行(无论由谁执行)。
import pandas as pd
# 示例数据
df = pd.DataFrame({
'task type': ['install', 'upgrade', 'install', 'remove', 'upgrade'],
'users': ['Dave', 'Carol', 'Mike', 'Alice', 'Dave']
})
leavers = ['Carol', 'Alice']
# Step 1: 获取离职人员执行过的所有唯一 task type
leaver_tasks = df.loc[df['users'].isin(leavers), 'task type'].unique()
# Step 2: 筛选 —— 排除所有出现在 leaver_tasks 中的 task type
result_df = df[~df['task type'].isin(leaver_tasks)]
print("✅ 过滤后数据(仅含未被离职人员执行过的任务类型):")
print(result_df)
# 输出:
# task type users
# 0 install Dave
# 2 install Mike
# 3 remove Alice ← 注意:此行会被过滤!因为 'remove' 本身未被 leavers 执行 → 实际保留?
# 等等 —— 需验证:本例中 leaver_tasks = ['upgrade', 'remove']?不!看数据:
# Carol → 'upgrade';Alice → 'remove' ⇒ leaver_tasks = ['upgrade', 'remove']
# 所以最终 result_df 只保留 'install' 相关行(索引 0 和 2)? 关键点:
df['task type'].isin(leaver_tasks)判断的是任务类型是否“有污点”(即曾被leavers执行),而非当前行用户是否为leaver。这是与df[~df['users'].isin(leavers)]的本质区别。
⚠️ 常见误区与注意事项
- ❌ 错误做法:
df[~df['users'].isin(leavers)]
→ 仅过滤离职员工的记录,但会错误保留“Dave执行的upgrade”(因该任务也被Carol执行过,应整体剔除)。 - ✅ 正确语义:“该任务类型是否具备洁净性” —— 任一leaver执行过,则整个类型失效。
- ? 若需统计各任务类型的执行频次(过滤后):
print("\n? 过滤后各任务类型执行次数(降序):") print(result_df.groupby('task type').size().sort_values(ascending=False))
? 扩展:支持多列关联场景
若需基于复合条件(如 ('task type', 'priority') 元组)判断“是否被leavers执行”,可改用:
leaver_pairs = set(df.loc[df['users'].isin(leavers), ['task type', 'priority']].apply(tuple, axis=1)) result_df = df[~df[['task type', 'priority']].apply(tuple, axis=1).isin(leaver_pairs)]
综上,核心是理解 isin() + ~ 的组合用于全局类型级屏蔽,而非行级过滤。掌握此模式,可高效解决权限隔离、职责审计、数据清洗等典型业务问题。

















