Pandas如何根据LAST_ACCESSED字段为用户分配登录状态编号
问题原因
你的代码存在几处语法和逻辑错误,直接导致运行失败:
- 比较运算符写错:Python中相等判断必须用双等号
==,你代码里全写的是单等号=(这是赋值符号,写在判断条件里会直接触发语法错误) - 括号不匹配:第一个if条件末尾多了多余的
],第二个elif的左括号没有对应闭合 - 空值判断逻辑错误:判断字段为空不能直接和自定义的
None列比对,需要用pandas自带的空值判断方法 - 缺少兜底逻辑:三个判断条件没有覆盖所有场景,会导致部分行的Status列出现空值
- 时间比较逻辑错误:时间类型字段不能直接和数字5比大小,要先算时间差再判断间隔
前置预处理
先把两个时间字段统一转成pandas的datetime格式,避免类型不对导致的比较错误:
import pandas as pd import numpy as np # 转时间格式,无效值自动转成空值NaT df1['LAST_ACCESSED'] = pd.to_datetime(df1['LAST_ACCESSED'], errors='coerce') df1['Run_date_Time'] = pd.to_datetime(df1['Run_date_Time'])
实现方案
方案1:修正原apply逻辑(适合千行级小数据量)
把自定义函数的语法、逻辑修正即可:
def flag(row): # 离线:无有效最后访问记录 if pd.isna(row['LAST_ACCESSED']): return 0 # 在线:最后访问时间等于统计运行时间 elif row['LAST_ACCESSED'] == row['Run_date_Time']: return 1 # 离开:最后访问时间比统计时间早5分钟以上(300秒=5分钟,可按需调整阈值) elif (row['Run_date_Time'] - row['LAST_ACCESSED']).total_seconds() > 300: return 2 # 兜底:访问间隔小于5分钟默认算在线,避免空值 else: return 1 df1['Status'] = df1.apply(flag, axis=1)
方案2:向量化实现(推荐,万行以上数据比apply快10~100倍)
不用逐行循环,用pandas原生条件赋值,性能更好:
df1['Status'] = np.select( condlist=[ pd.isna(df1['LAST_ACCESSED']), df1['LAST_ACCESSED'] == df1['Run_date_Time'], (df1['Run_date_Time'] - df1['LAST_ACCESSED']).dt.total_seconds() > 300 ], choicelist=[0, 1, 2], default=1 )
最终映射效果
生成的Status列完全匹配需求规则:
- 0:离线,无有效访问记录
- 1:可用/在线,最后访问时间等于统计时间,或距统计时间间隔小于5分钟
- 2:离开,最后访问时间距统计时间超过5分钟
内容的提问来源于stack exchange,提问作者SamAmankwaaDS
相关产品推荐
相关产品推荐

