如何基于两列合并两个DataFrame并按时间区间匹配数据?
解决DataFrame多键合并与时间区间匹配问题
第一步:先修复合并键的语法错误
你之前写的data.merge(data_2, on='Date' & 'About')是语法错误,指定多列作为合并键时,要把列名放在列表里,正确写法是:
merged_df = pd.merge(data, data_2, on=['Date', '姓名'])
不过这只是基础的等值合并,还满足不了你的时间区间匹配需求,继续往下看。
第二步:实现时间区间匹配的合并逻辑
因为你需要同一参与者的测试数据按时间区间对应(比如某段日期用原数据,之后用测试数据),得先统一日期格式,再做区间判断:
- 统一日期为datetime类型
先把两个表的日期列转成datetime,避免格式不兼容:
import pandas as pd data['Date'] = pd.to_datetime(data['Date']) data_2['测试日期'] = pd.to_datetime(data_2['测试日期'])
- 处理时间分割规则
- 如果所有参与者用同一个时间分割点(比如你举例的2022-9-16):
split_date = pd.to_datetime('2022-09-16')
- 如果每个参与者的分割点不同,先做一个映射表关联到主表:
split_map = pd.DataFrame({ '姓名': ['张三', '李四'], '分割日期': ['2022-09-16', '2022-10-01'] }) split_map['分割日期'] = pd.to_datetime(split_map['分割日期']) data = pd.merge(data, split_map, on='姓名', how='left')
- 按时间区间合并替换数据
先把测试数据合并到主表,再用条件判断替换对应区间的数据:
# 先把测试数据按姓名+日期匹配到主表 data = pd.merge( data, data_2, left_on=['姓名', 'Date'], right_on=['姓名', '测试日期'], how='left', suffixes=('_原', '_测试') ) # 按时间区间替换数据 # 统一分割点用这个:data['Date'] > split_date data['目标列'] = np.where( data['Date'] > data['分割日期'], data['目标列_测试'], data['目标列_原'] ) # 清理多余中间列 data.drop(['测试日期', '目标列_原', '目标列_测试', '分割日期'], axis=1, inplace=True)
更灵活的多测试场景:用merge_asof
如果data_2里是参与者的多次测试数据,需要自动匹配当前日期之前的最新测试结果,用merge_asof更高效:
# 先对两个表按姓名+日期排序 data_sorted = data.sort_values(['姓名', 'Date']) data_2_sorted = data_2.sort_values(['姓名', '测试日期']) # 按姓名分组,匹配每个日期前最近的测试数据 merged_df = pd.merge_asof( data_sorted, data_2_sorted, left_on='Date', right_on='测试日期', by='姓名', direction='backward' # 取小于等于当前日期的最近测试记录 )
内容的提问来源于stack exchange,提问作者E Jager de
相关产品推荐
相关产品推荐

