基于第二个DataFrame对第一个DataFrame列进行线性插值的实现方案
解决方案
步骤1:准备数据
先把示例数据构造出来,确保两个DataFrame都按col1严格升序:
import pandas as pd df1 = pd.DataFrame({'col1': [0, 10, 20, 30]}) df2 = pd.DataFrame({'col1': [0, 5, 15, 25, 33], 'val': [0, 2, 4, 5, 8]})
步骤2:用两次merge_asof获取完整插值所需信息
利用merge_asof的方向参数,一次性拿到每个df1.col1对应的左右邻点(df2中最接近的前后两个点)的col1和val:
# 找df2中 <= 当前df1.col1 的最大点(左邻点) left_neighbor = pd.merge_asof(df1, df2, on='col1', direction='backward', suffixes=('', '_left')) # 找df2中 >= 当前df1.col1 的最小点(右邻点) right_neighbor = pd.merge_asof(df1, df2, on='col1', direction='forward', suffixes=('', '_right')) # 合并左右邻点的信息到同一张表 combined = left_neighbor.merge(right_neighbor, on='col1')
步骤3:计算线性插值
根据左右邻点的数值,分情况计算:
- 如果左右邻点是同一个(完全匹配),直接取对应
val - 否则用线性插值公式计算:
左val + (右val - 左val) * (当前col1 - 左col1) / (右col1 - 左col1)
代码实现:
combined['val'] = combined.apply( lambda row: row['val_left'] if row['col1_left'] == row['col1_right'] else row['val_left'] + (row['val_right'] - row['val_left']) * (row['col1'] - row['col1_left']) / (row['col1_right'] - row['col1_left']), axis=1 ) # 提取最终结果 final_result = combined[['col1', 'val']] print(final_result)
运行后输出完全符合预期:
col1 val 0 0 0.00 1 10 3.00 2 20 4.50 3 30 6.875
方案优势
- 用pandas原生的
merge_asof高效处理有序数据的匹配,比手动遍历查找速度快,适合大数据量场景 - 一次性拿到左右邻点的完整
col1和val信息,解决了你之前缺对应df2列信息的问题 - 逻辑直观,插值公式完全对应线性插值的数学定义,容易理解和维护
内容的提问来源于stack exchange,提问作者roulette01
相关产品推荐
相关产品推荐

