如何根据趋势从DataFrame同日期多值中选取对应高低值?
DataFrame 按规则筛选值的实现方案
问题背景
原始DataFrame数据:
| ID | Date | val |
|---|---|---|
| ABC | 2022-04-05 | 100 |
| ABC | 2023-02-04 | 200 |
| ABC | 2023-02-04 | 300 |
| ABC | 2023-05-10 | 400 |
| ABC | 2023-06-27 | 250 |
| ABC | 2023-06-27 | 200 |
期望处理结果:
| ID | Date | val |
|---|---|---|
| ABC | 2022-04-05 | 100 |
| ABC | 2023-02-04 | 300 |
| ABC | 2023-05-10 | 400 |
| ABC | 2023-06-27 | 200 |
规则说明
- 同一日期存在多个值时,与前一日期的最终值对比
- 若当前日期所有值均高于前一日期值(上升趋势),取该日期最大值
- 若当前日期所有值均低于前一日期值(下降趋势),取该日期最小值
- 已知同一日期的所有值要么全高于、要么全低于前一日期值
实现方案
可以完全实现该需求,以下是基于Pandas的代码实现:
代码示例
import pandas as pd # 构造原始数据 df = pd.DataFrame({ 'ID': ['ABC', 'ABC', 'ABC', 'ABC', 'ABC', 'ABC'], 'Date': ['2022-04-05', '2023-02-04', '2023-02-04', '2023-05-10', '2023-06-27', '2023-06-27'], 'val': [100, 200, 300, 400, 250, 200] }) # 转换日期格式并按ID、日期排序 df['Date'] = pd.to_datetime(df['Date']) df = df.sort_values(['ID', 'Date']).reset_index(drop=True) # 按ID和日期分组,计算每组的最小、最大值 grouped = df.groupby(['ID', 'Date']).agg( val_min=('val', 'min'), val_max=('val', 'max') ).reset_index() # 初始化最终值列,第一行直接取对应值(无前置日期) grouped['val'] = grouped['val_min'] # 遍历后续行,根据趋势选择对应值 for idx in range(1, len(grouped)): prev_val = grouped.loc[idx-1, 'val'] curr_min = grouped.loc[idx, 'val_min'] curr_max = grouped.loc[idx, 'val_max'] if curr_min > prev_val: grouped.loc[idx, 'val'] = curr_max elif curr_max < prev_val: grouped.loc[idx, 'val'] = curr_min # 整理成目标格式的结果 result = grouped[['ID', 'Date', 'val']] print(result)
运行结果
ID Date val 0 ABC 2022-04-05 100 1 ABC 2023-02-04 300 2 ABC 2023-05-10 400 3 ABC 2023-06-27 200
逻辑说明
- 数据预处理:将Date转为datetime类型并排序,确保分组和顺序正确
- 分组聚合:按ID和Date分组,计算每组的最小、最大值,方便后续趋势判断
- 趋势判断与取值:从第二行开始,对比当前组的极值与前一行的最终值,根据上升/下降趋势选择对应最值
- 结果整理:提取需要的列,得到目标DataFrame
内容的提问来源于stack exchange,提问作者ASD
相关产品推荐
相关产品推荐

