如何在Pandas中移除日期不连续的特定用户全量DataFrame数据
问题:移除日期序列不连续的用户数据
原始DataFrame数据:
date consumption customer_id 2018-01-01 12 111 2018-01-02 12 111 2018-01-03 14 111 2018-01-05 12 111 2018-01-06 45 111 2018-01-07 34 111 2018-01-01 23 112 2018-01-02 23 112 2018-01-03 45 112 2018-01-04 34 112 2018-01-05 23 112 2018-01-06 34 112 2018-01-01 23 113 2018-01-02 34 113 2018-01-03 45 113 2018-01-04 34 113
其中customer_id=111的用户日期序列不连续(缺失2018-01-04),需要移除该用户的所有数据,得到如下结果:
date consumption customer_id 2018-01-01 23 112 2018-01-02 23 112 2018-01-03 45 112 2018-01-04 34 112 2018-01-05 23 112 2018-01-06 34 112 2018-01-01 23 113 2018-01-02 34 113 2018-01-03 45 113 2018-01-04 34 113
解决方案
通过分组检查日期连续性的方式实现,具体步骤如下:
步骤1:转换日期格式并准备数据
先确保date列是datetime类型,方便后续日期计算:
import pandas as pd # 构造原始DataFrame(若从文件读取,替换为pd.read_csv等方法即可) data = { 'date': ['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06', '2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04'], 'consumption': [12,12,14,12,45,34,23,23,45,34,23,34,23,34,45,34], 'customer_id': [111]*6 + [112]*6 + [113]*4 } df = pd.DataFrame(data) # 将date列转为datetime类型 df['date'] = pd.to_datetime(df['date'])
步骤2:定义日期连续性检查函数
编写函数判断单个用户的日期序列是否完整连续:
def is_continuous_dates(group): # 生成该用户日期范围的完整序列(从最早到最晚,每天一条) full_date_range = pd.date_range(start=group['date'].min(), end=group['date'].max(), freq='D') # 对比完整序列长度和用户实际存在的去重日期数量,相等则说明无缺失 return len(full_date_range) == group['date'].nunique()
步骤3:筛选有效用户并过滤数据
按customer_id分组检查,保留日期连续的用户,再过滤原始DataFrame:
# 分组检查每个用户的日期连续性,返回布尔值Series valid_check = df.groupby('customer_id').apply(is_continuous_dates) # 提取日期连续的用户ID列表 valid_customer_ids = valid_check[valid_check].index.tolist() # 过滤出有效用户的数据 result_df = df[df['customer_id'].isin(valid_customer_ids)]
可选:另一种检查方式(相邻日期差值)
如果只需要检查现有日期的相邻间隔是否为1天,也可以用这种方式:
def is_continuous_dates_v2(group): # 对日期排序后计算相邻日期的天数差 sorted_dates = group['date'].sort_values() day_diff = sorted_dates.diff().dt.days.dropna() # 检查所有差值是否都为1 return (day_diff == 1).all() # 同样分组筛选 valid_check_v2 = df.groupby('customer_id').apply(is_continuous_dates_v2) valid_customer_ids_v2 = valid_check_v2[valid_check_v2].index.tolist() result_df_v2 = df[df['customer_id'].isin(valid_customer_ids_v2)]
验证结果
运行代码后,result_df就是符合要求的数据集,打印后与目标结果一致。
内容的提问来源于stack exchange,提问作者Naeem
相关产品推荐
相关产品推荐

