基于多列值清理DataFrame:保留用户最早完成状态记录
数据清理:保留每个用户最早的completed=yes记录
原始数据
| date | name | completed | |
|---|---|---|---|
| aaa@xyz.com | 01-07-2022 12:40:00 | james | no |
| aaa@xyz.com | 01-07-2022 12:10:00 | james | yes |
| aaa@xyz.com | 01-07-2022 12:19:00 | james | yes |
| aaa@xyz.com | 01-07-2022 12:30:00 | james | no |
| bbb@xyz.com | 02-07-2022 08:04:00 | clark | yes |
| bbb@xyz.com | 02-07-2022 08:08:00 | clark | yes |
| bbb@xyz.com | 02-07-2022 08:13:00 | clark | no |
| bbb@xyz.com | 02-07-2022 08:28:00 | clark | no |
需求
针对每个name与email的组合,仅保留completed字段为“yes”的最早date记录。
预期结果
| date | name | completed | |
|---|---|---|---|
| aaa@xyz.com | 01-07-2022 12:10:00 | james | yes |
| bbb@xyz.com | 02-07-2022 08:04:00 | clark | yes |
用户尝试的代码及问题
用户原本的代码:
df = df.sort_values('date') df = df.groupby('date').first()
这段代码存在两个问题:
- 错误地按
date分组,而非按email和name的组合分组 - 分组后会将
date设为索引,不符合输出格式要求
正确解决方案
方法一:保留原索引
import pandas as pd # 先过滤出completed为yes的记录 df_filtered = df[df['completed'] == 'yes'] # 将date转换为datetime类型,确保时间排序正确 df_filtered['date'] = pd.to_datetime(df_filtered['date'], format='%d-%m-%Y %H:%M:%S') # 按email和name分组,获取每组最早date的行索引 earliest_indices = df_filtered.groupby(['email', 'name'])['date'].idxmin() # 提取对应行,保留原索引 result = df_filtered.loc[earliest_indices] # 恢复date列的原始字符串格式(可选) result['date'] = result['date'].dt.strftime('%d-%m-%Y %H:%M:%S')
方法二:重置索引(更简洁)
import pandas as pd # 转换date为datetime类型 df['date'] = pd.to_datetime(df['date'], format='%d-%m-%Y %H:%M:%S') # 过滤后排序,按email和name分组取第一条,重置索引避免分组列为索引 result = df[df['completed'] == 'yes'].sort_values('date').groupby(['email', 'name']).first().reset_index() # 恢复date的字符串格式 result['date'] = result['date'].dt.strftime('%d-%m-%Y %H:%M:%S')
两种方法都能得到符合预期的结果,且不会改变需求中的列结构。
内容的提问来源于stack exchange,提问作者User277883
相关产品推荐
相关产品推荐

