基于条件提取DataFrame中最后一条和倒数第三条In-progress记录
Pandas按ID提取指定状态的特定时间点记录
解决方案代码
import pandas as pd # 假设原始数据存储在DataFrame df中 # 1. 筛选出State为"In-progress"的记录 filtered_df = df[df['State'] == 'In-progress'] # 2. 为每个ID提取目标时间点:最后一个和倒数第三个In-progress的Time def get_target_time_points(group): # 对当前ID下的唯一Time值排序,确保时间顺序正确 sorted_times = sorted(group['Time'].unique()) # 仅当时间点数量≥3时才取倒数第三个,否则只取最后一个 target_positions = [-1, -3] if len(sorted_times) >= 3 else [-1] return [sorted_times[pos] for pos in target_positions] # 按ID分组获取目标时间,展开为(ID, Time)配对 id_time_pairs = filtered_df.groupby('ID').apply(get_target_time_points).explode() id_time_pairs = id_time_pairs.reset_index(name='Time') # 3. 筛选出符合条件的所有记录 result_df = pd.merge(filtered_df, id_time_pairs, on=['ID', 'Time'])
步骤说明
- 筛选目标状态记录:先过滤掉非"In-progress"的行,缩小处理范围。
- 提取目标时间点:对每个ID分组后,整理并排序该ID下所有的In-progress时间点,按需求选取最后一个和倒数第三个时间点(若时间点不足3个则仅保留最后一个)。
- 匹配筛选最终记录:通过合并操作,从筛选后的数据集里取出所有符合(ID, Time)配对的记录,得到结果。
备注:如果Time字段包含完整日期或需要更精准的时间排序,建议先转换为时间类型:
filtered_df['Time'] = pd.to_datetime(filtered_df['Time'])
期望结果示例
| Time | State | ID | Ref | Name |
|---|---|---|---|---|
| 10:00 | In-progress | 54887 | 1 | Jim |
| 10:00 | In-progress | 54887 | 2 | Jon |
| 10:00 | In-progress | 54887 | 3 | Rob |
| 10:00 | In-progress | 54887 | 4 | Sam |
| 12:00 | In-progress | 54887 | 1 | Jim |
| 12:00 | In-progress | 54887 | 2 | Jon |
| 12:00 | In-progress | 54887 | 3 | Rob |
| 12:00 | In-progress | 54887 | 4 | Sam |
| 10:00 | In-progress | 65228 | a | Anya |
| 10:00 | In-progress | 65228 | b | Lot |
| 10:00 | In-progress | 65228 | c | Ted |
| 10:00 | In-progress | 65228 | d | Tom |
| 12:00 | In-progress | 65228 | a | Anya |
| 12:00 | In-progress | 65228 | b | Lot |
| 12:00 | In-progress | 65228 | c | Ted |
| 12:00 | In-progress | 65228 | d | Tom |
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

