如何在Python DataFrame中按日期区间匹配添加CEO列?
实现方案
下面是几种实用的实现方式,按简便性和效率排序:
1. 区间索引匹配(最直观简便)
利用pandas的IntervalIndex直接判断日期所属区间,代码简洁可读性强:
import pandas as pd # 统一转换日期列为datetime类型 df1['Date'] = pd.to_datetime(df1['Date']) df2['Start'] = pd.to_datetime(df2['Start']) df2['End'] = pd.to_datetime(df2['End']) # 为df2创建日期区间列 df2['date_range'] = pd.IntervalIndex.from_arrays(df2['Start'], df2['End'], closed='both') # 定义匹配逻辑:按公司筛选后检查日期是否在区间内 def match_ceo(row): company_records = df2[df2['Company'] == row['Company']] matched = company_records[company_records['date_range'].contains(row['Date'])] return matched['CEO'].iloc[0] if not matched.empty else None # 应用到df1生成新列 df1['CEO'] = df1.apply(match_ceo, axis=1)
运行后df1结果:
| Date | Company | CEO |
|---|---|---|
| 2022-01-04 | Apple | Tim Cook |
| 2020-01-03 | Apple | None |
| 2000-01-03 | Apple | None |
2. 合并后筛选(基础通用)
先按Company合并两个DataFrame,再筛选符合日期区间的记录,最后映射回原df1:
import pandas as pd # 转换日期类型 df1['Date'] = pd.to_datetime(df1['Date']) df2['Start'] = pd.to_datetime(df2['Start']) df2['End'] = pd.to_datetime(df2['End']) # 按Company左连接 temp_df = pd.merge(df1, df2, on='Company', how='left') # 筛选日期在区间内的行 valid_mask = (temp_df['Date'] >= temp_df['Start']) & (temp_df['Date'] <= temp_df['End']) # 将匹配的CEO值映射回原df1 df1['CEO'] = temp_df.loc[valid_mask, ['Date', 'Company', 'CEO']].merge(df1, on=['Date', 'Company'], how='left')['CEO']
3. 有序日期匹配(高效大数据场景)
如果日期数据是有序的,使用merge_asof可大幅提升匹配效率,适合百万级以上数据量:
import pandas as pd # 转换日期并按日期排序 df1['Date'] = pd.to_datetime(df1['Date']) df2['Start'] = pd.to_datetime(df2['Start']) df2['End'] = pd.to_datetime(df2['End']) df1_sorted = df1.sort_values('Date').reset_index(drop=True) df2_sorted = df2.sort_values('Start').reset_index(drop=True) # 按Company分组匹配最近的Start日期,再验证是否在End之前 merged = pd.merge_asof( df1_sorted, df2_sorted, left_on='Date', right_on='Start', by='Company', direction='backward' ) # 筛选符合条件的记录,无匹配则设为None df1_sorted['CEO'] = merged.apply(lambda x: x['CEO'] if x['Date'] <= x['End'] else None, axis=1) # 恢复原df1的顺序 df1 = df1_sorted.sort_index().reset_index(drop=True)
注意事项
- 若同一公司同一日期区间存在多个CEO,需额外处理逻辑(如取第一个、拼接所有值);
- 所有方法必须确保日期列是
datetime类型,否则无法进行区间比较; - 数据量较大时优先选方法3,其次是方法1,避免方法2的全量合并。
内容的提问来源于stack exchange,提问作者user17540557
相关产品推荐
相关产品推荐

