如何基于DataFrame分组记录检测指定字符串的日期维度缺失情况
问题解决:检测分组内指定字符串的日期缺失情况
原始数据
首先定义初始的DataFrame:
import pandas as pd import numpy as np # 数据存储在字典中 details = { 'address_id': [111, 111, 111, 111, 222, 222, 222, 222, 333], 'mydate':['2022-01-24', '2022-01-24', '2022-03-28', '2022-03-28', '2022-01-24', '2022-01-24', '2022-03-28', '2022-03-28', '2022-01-24'], 'mystring': ['att', 'verizon', 'comcast', 'verizon', 'att', 'verizon', 'att', 'verizon', 'verizon'] } df = pd.DataFrame(details)
需求说明
针对address_id分组,检测指定字符串att的缺失情况:
- 若同一分组中,
att在较早日期存在,但在较晚日期缺失,则该较晚日期的所有记录的ismissing标记为True - 若
att在早、晚日期均存在,或分组只有单个日期,则ismissing标记为False
解决方案代码
# 将mydate转为日期类型,确保日期排序逻辑正确 df['mydate'] = pd.to_datetime(df['mydate']) # 按address_id分组,计算每个日期组是否包含att,以及日期的先后排名 grouped = df.groupby('address_id').apply( lambda x: x.assign( has_att=x['mystring'].eq('att').any(), date_rank=x['mydate'].rank(method='dense', ascending=True) ) ).reset_index(drop=True) # 提取每个分组的关键信息:最早日期是否有att、分组内的最大日期排名 group_summary = grouped.groupby('address_id').agg( early_has_att=('has_att', lambda x: x[grouped['date_rank'] == 1].iloc[0]), max_rank=('date_rank', 'max') ) # 合并信息并计算ismissing列 df_final = grouped.merge(group_summary, on='address_id') df_final['ismissing'] = ( df_final['early_has_att'] & (df_final['date_rank'] > 1) & ~df_final['has_att'] ) # 整理列顺序并将日期转回字符串格式 df_final = df_final[['address_id', 'mydate', 'mystring', 'ismissing']] df_final['mydate'] = df_final['mydate'].dt.strftime('%Y-%m-%d') print(df_final)
输出结果
address_id mydate mystring ismissing 0 111 2022-01-24 att False 1 111 2022-01-24 verizon False 2 111 2022-03-28 comcast True 3 111 2022-03-28 verizon True 4 222 2022-01-24 att False 5 222 2022-01-24 verizon False 6 222 2022-03-28 att False 7 222 2022-03-28 verizon False 8 333 2022-01-24 verizon False
逻辑解释
- 日期类型转换:把
mydate转为datetime类型,避免字符串排序的误差 - 分组计算基础指标:
- 标记每个日期组内是否存在
att(has_att) - 给分组内的日期分配排名(
date_rank),最早日期为1,后续日期依次递增
- 标记每个日期组内是否存在
- 分组汇总关键信息:
- 确认分组的最早日期是否包含
att(early_has_att) - 获取分组内的最大日期排名,判断是否存在多日期的情况
- 确认分组的最早日期是否包含
- 生成缺失标记:
当且仅当「最早日期有att」「当前日期不是最早」「当前日期无att」三个条件同时满足时,ismissing设为True,其余情况均为False
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

