存在重复日期时为每条记录选最早日期并循环随机取值
问题描述
我有一个每条identifier对应多个日期的表格,示例数据如下:
| identifier | date | value |
|---|---|---|
| a | 1985-01-01 | ex1 |
| a | 1985-01-01 | ex2 |
| a | 1985-01-03 | ex3 |
| b | 1990-01-05 | ex1 |
| b | 1990-05-10 | ex4 |
| c | 1987-01-01 | ex1 |
| c | 1987-01-01 | ex3 |
| d | 1986-01-01 | ex1 |
| d | 1986-01-01 | ex3 |
我原本用这段代码提取每组identifier的最早日期记录:
df2 = df.loc[df.groupby('identifier')['date'].idxmin()]
但当同一identifier的最早日期存在多条记录时,会默认选中value字母序靠前的那条。我想要实现循环轮选:第一次遇到重复最早日期选第一条,第二次选第二条,有第三条的话第三次选第三条,以此循环。预期输出如下:
| identifier | date | value |
|---|---|---|
| a | 1985-01-01 | ex1 |
| b | 1990-01-05 | ex1 |
| c | 1987-01-01 | ex3 |
| d | 1986-01-01 | ex1 |
解决方案
可以通过以下步骤修改代码实现循环轮选的需求:
- 筛选每组最早日期的候选记录:先过滤出所有
date等于该组最早日期的记录,只处理这些重复的候选数据; - 添加组内序号:给每个
identifier下的候选记录标记组内序号,方便后续定位选取; - 轮选逻辑实现:用全局计数器配合取模运算,实现循环选取不同序号的记录。
具体代码实现:
import pandas as pd # 示例数据 data = { 'identifier': ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], 'date': ['1985-01-01', '1985-01-01', '1985-01-03', '1990-01-05', '1990-05-10', '1987-01-01', '1987-01-01', '1986-01-01', '1986-01-01'], 'value': ['ex1', 'ex2', 'ex3', 'ex1', 'ex4', 'ex1', 'ex3', 'ex1', 'ex3'] } df = pd.DataFrame(data) # 步骤1:获取每组最早日期并筛选候选记录 min_dates = df.groupby('identifier')['date'].min().reset_index(name='min_date') candidates = df.merge(min_dates, on='identifier') candidates = candidates[candidates['date'] == candidates['min_date']] # 步骤2:给每个组内的候选记录添加序号 candidates['group_rank'] = candidates.groupby('identifier').cumcount() # 步骤3:循环轮选 selected = [] counter = 0 for name, group in candidates.groupby('identifier'): num_options = len(group) pick_idx = counter % num_options selected.append(group.iloc[pick_idx]) counter += 1 # 整理结果 df2 = pd.DataFrame(selected).drop(columns=['min_date', 'group_rank']) print(df2)
运行后输出与预期一致:
identifier date value 0 a 1985-01-01 ex1 1 b 1990-01-05 ex1 2 c 1987-01-01 ex3 3 d 1986-01-01 ex1
代码说明
- 用
merge筛选候选记录,避免处理无关数据,提升效率; cumcount()生成组内序号,默认按原数据顺序编号;- 全局计数器
counter通过取模运算实现循环:比如某组有2条候选记录时,第1次选第0位,第2次选第1位,第3次回到第0位,以此往复。
内容的提问来源于stack exchange,提问作者K3it4r0
相关产品推荐
相关产品推荐

