基于最新起始CASE_ID筛选DataFrame并保留全部行的实现问题
问题:筛选DataFrame中每个用户的最新CASE_ID的全部行
需求说明
我是Python新手,现在需要实现:根据每个用户的最新起始CASE_ID(即对应STATUS为Start的时间最晚的CASE_ID),筛选出该CASE_ID对应的全部行。
示例数据
原DataFrame:
| ID | CASE ID | CHANGE_TMS | STATUS |
|---|---|---|---|
| 00000001 | Case 1 | 15:12:10 | Start |
| 00000001 | Case 1 | 15:14:45 | END |
| 00000001 | Case 2 | 17:29:23 | Start |
| 00000001 | Case 2 | 18:30:23 | End |
期望结果:
| ID | CASE ID | CHANGE_TMS | STATUS |
|---|---|---|---|
| 00000001 | Case 2 | 17:29:23 | Start |
| 00000001 | Case 2 | 18:30:23 | End |
我的尝试代码
import pandas as pd file_path = r'C:\path' # Read the csv file and extract the specified columns columns_to_keep=['CUSTOMER_ID', 'CASE_ID', 'CHANGE_TMS','STATUS'] df = pd.read_csv(file_path, usecols=columns_to_keep) #change column to datetime type df['CHANGE_TMS'] = pd.to_datetime(df['CHANGE_TMS']) #sent the index df.set_index('CASE_ID', inplace=True) #sort the timestamp column df.sort_values(by=['CUSTOMER_ID', 'CHANGE_TMS'], inplace=True) last_case_indices = df.groupby('CASE_ID')['CHANGE_TMS'].first() print(last_case_indices)
解决方案
你的代码问题在于:没有按用户(CUSTOMER_ID)分组去定位每个用户的最新CASE_ID,反而把CASE_ID设为索引,偏离了需求方向。下面是修正后的实现:
步骤说明
- 先筛选出所有
STATUS为Start的行,因为我们要找的是起始时间最晚的CASE_ID - 按
CUSTOMER_ID分组,找到每个用户下CHANGE_TMS最大的那一行(即最新的Start),提取对应的CASE_ID - 用这些
CASE_ID去原DataFrame中筛选出所有属于该CASE的行
完整代码
import pandas as pd file_path = r'C:\path' # 读取指定列 columns_to_keep=['CUSTOMER_ID', 'CASE_ID', 'CHANGE_TMS','STATUS'] df = pd.read_csv(file_path, usecols=columns_to_keep) # 转换时间格式(注意如果你的CHANGE_TMS只有时分秒,会自动补当前日期,不影响排序) df['CHANGE_TMS'] = pd.to_datetime(df['CHANGE_TMS']) # 1. 筛选所有Start状态的行,找到每个用户最新的Start对应的CASE_ID start_rows = df[df['STATUS'].str.lower() == 'start'] # 统一小写避免大小写问题 latest_case_per_user = start_rows.loc[start_rows.groupby('CUSTOMER_ID')['CHANGE_TMS'].idxmax(), 'CASE_ID'] # 2. 筛选原DataFrame中属于这些CASE_ID的所有行 result_df = df[df['CASE_ID'].isin(latest_case_per_user)] print(result_df)
代码解释
start_rows.groupby('CUSTOMER_ID')['CHANGE_TMS'].idxmax():找到每个用户下时间最晚的Start行的索引loc[..., 'CASE_ID']:提取这些索引对应的CASE_IDisin(latest_case_per_user):筛选原DataFrame中CASE_ID在列表里的所有行
如果你的数据中每个CASE_ID可能跨用户,还可以加上CUSTOMER_ID的匹配,确保准确性:
# 扩展:如果CASE_ID可能跨用户,同时匹配用户和CASE_ID latest_case_info = start_rows.loc[start_rows.groupby('CUSTOMER_ID')['CHANGE_TMS'].idxmax(), ['CUSTOMER_ID', 'CASE_ID']] result_df = df.merge(latest_case_info, on=['CUSTOMER_ID', 'CASE_ID'], how='inner')
内容的提问来源于stack exchange,提问作者Mihail Florea
相关产品推荐
相关产品推荐

