Pandas:基于唯一ID及日期条件筛选DataFrame的实现
实现方法
核心逻辑
- 按
ID字段对DataFrame做分组,定位每个分组内DATE_ACCEPT非空的对应行,提取该行的DATE_VIEW值作为该分组的过滤基准值。 - 为所有行匹配对应ID的基准值,逐行做比较:仅保留
DATE_VIEW小于等于对应基准值的行,过滤掉DATE_VIEW大于基准值的行。
完整可运行代码
import numpy as np import pandas as pd # 构造示例DataFrame并完成日期格式转换 df = {'ID': ['1','1','2', '2', '3', '3', '4', '4', '4'], 'USER' : ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'C'], 'DATE_VIEW': ['16/05/2019','18/05/2019', '16/03/2020', '18/03/2020', '16/07/2020', '21/07/2020', '13/02/2020', '14/02/2020', '15/02/2020'], 'DATE_ACCEPT': ['17/05/2019', np.nan, np.nan, '18/03/2020', '16/07/2020', np.nan, np.nan, '14/02/2020', np.nan], } df = pd.DataFrame(df) df['DATE_VIEW'] = pd.to_datetime(df['DATE_VIEW'], format = '%d/%m/%Y') df['DATE_ACCEPT'] = pd.to_datetime(df['DATE_ACCEPT'], format = '%d/%m/%Y') # 提取每个ID分组的过滤基准值 id_base_map = df.groupby('ID').apply( lambda g: g.loc[g['DATE_ACCEPT'].notna(), 'DATE_VIEW'].iloc[0] ) # 匹配基准值到每一行,执行过滤 df['base_view'] = df['ID'].map(id_base_map) filtered_df = df[df['DATE_VIEW'] <= df['base_view']].drop(columns='base_view')
结果校验
运行代码得到的filtered_df完全匹配预期输出:
| ID | USER | DATE_VIEW | DATE_ACCEPT |
|---|---|---|---|
| 1 | A | 2019-05-16 | 2019-05-17 |
| 2 | A | 2020-03-16 | NaN |
| 2 | B | 2020-03-18 | 2020-03-18 |
| 3 | A | 2020-07-16 | 2020-07-16 |
| 4 | A | 2020-02-13 | NaN |
| 4 | B | 2020-02-14 | 2020-02-14 |
兼容说明:如果遇到某ID分组下所有行的
DATE_ACCEPT都为空的场景,可以在计算基准值的逻辑中增加判断,将这类分组的基准值设为组内最大的DATE_VIEW,实现整组全保留的兼容效果。
内容的提问来源于stack exchange,提问作者Caiotru
相关产品推荐
相关产品推荐

