基于另一DataFrame最近值计算列及时间插值实现方法
问题描述
现有两个Pandas DataFrame:coarse和fine:
fine包含start_time、end_time、start_price、end_price列coarse包含start_time、end_time列
所有时间均为Pandas Timestamp对象(如2016-12-12 01:03:13.15231+00:00)
需求:为coarse新增start_price和end_price列:
coarse.start_price取fine中start_time与coarse.start_time最接近的对应start_priceend_price逻辑与start_price完全一致
示例数据
初始coarse数据
start_time end_time 2016-12-12 01:00:00.000+00:00 2016-12-12 02:00:00.000+00:00 2016-12-12 02:00:00.000+00:00 2016-12-12 03:00:00.000+00:00 2016-12-12 03:00:00.000+00:00 2016-12-12 03:30:00.000+00:00
fine数据
start_time end_time start_price 2016-12-12 00:59:00.000+00:00 2016-12-12 01:12:00.000+00:00 2.3 2016-12-12 01:12:00.000+00:00 2016-12-12 01:15:00.000+00:00 4.5 2016-12-12 01:15:00.000+00:00 2016-12-12 01:45:00.000+00:00 5.7 2016-12-12 01:45:00.000+00:00 2016-12-12 01:55:00.000+00:00 8.8 2016-12-12 01:55:00.000+00:00 2016-12-12 02:15:00.000+00:00 9.9 2016-12-12 02:15:00.000+00:00 2016-12-12 02:16:00.000+00:00 11.2 2016-12-12 02:16:00.000+00:00 2016-12-12 02:31:00.000+00:00 13.5 2016-12-12 02:31:00.000+00:00 2016-12-12 02:45:00.000+00:00 14.8 2016-12-12 02:45:00.000+00:00 2016-12-12 02:59:00.000+00:00 15.9 2016-12-12 02:59:00.000+00:00 2016-12-12 03:31:00.000+00:00 16.0
处理后coarse结果
start_time end_time start_price 2016-12-12 01:00:00.000+00:00 2016-12-12 02:00:00.000+00:00 2.3 2016-12-12 02:00:00.000+00:00 2016-12-12 03:00:00.000+00:00 9.9 2016-12-12 03:00:00.000+00:00 2016-12-12 03:30:00.000+00:00 16.0
解决方案一:最近邻匹配
利用Pandas的merge_asof实现简洁高效的最近邻匹配,步骤如下:
import pandas as pd # 确保两个DataFrame的时间列排序(merge_asof要求输入已排序) fine_sorted = fine.sort_values('start_time') coarse_sorted = coarse.sort_values('start_time') # 匹配start_price:找与coarse.start_time最接近的fine.start_time对应的价格 coarse_matched = pd.merge_asof( coarse_sorted, fine_sorted[['start_time', 'start_price']], on='start_time', direction='nearest' ) # 同理匹配end_price fine_end_sorted = fine.sort_values('end_time') coarse_matched = pd.merge_asof( coarse_matched, fine_end_sorted[['end_time', 'end_price']], on='end_time', direction='nearest' ) # 恢复原coarse的行顺序(若之前排序打乱了原顺序) coarse_matched = coarse_matched.sort_index()
说明
direction='nearest'会自动匹配与目标时间距离最近的记录- 若存在两个时间距离完全相等的情况,默认取较早的记录,可通过
allow_exact_matches参数调整规则
解决方案二:时间插值计算价格
如果需要基于时间间隔进行插值(如线性插值)得到目标时间点的价格,可按以下方式实现:
import pandas as pd # 处理start_price的时间插值 # 构建以fine.start_time为索引的价格序列并排序 price_series = fine.set_index('start_time')['start_price'].sort_index() # 合并原时间点与coarse的目标时间点,进行时间插值后提取目标时间的价格 coarse['start_price'] = price_series.reindex( price_series.index.union(coarse['start_time']) ).interpolate(method='time').loc[coarse['start_time']].values # 同理处理end_price的插值 end_price_series = fine.set_index('end_time')['end_price'].sort_index() coarse['end_price'] = end_price_series.reindex( end_price_series.index.union(coarse['end_time']) ).interpolate(method='time').loc[coarse['end_time']].values
说明
method='time'会根据时间间隔进行线性插值,适合时间序列数据- 可替换为
linear、nearest等其他插值方法,根据业务需求调整 - 若目标时间超出
fine的时间范围,默认沿用边界值,可通过limit_direction参数控制外插规则
内容的提问来源于stack exchange,提问作者student010101
相关产品推荐
相关产品推荐

