You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas如何按区间匹配从另一DataFrame填充空值更新列值

可行实现方案

普通等值left join无法生效的核心原因是匹配规则包含非等值区间判断,且一个区间可能匹配多条largedf记录,必须搭配聚合逻辑取最小值,不能直接关联后用fillna处理。以下分别提供Pandas和SQL的可直接运行实现:


Pandas 实现

如果数据量在十万级以内,用分组缓存+逐行匹配的逻辑即可,逻辑完全贴合需求,不需要依赖额外第三方库:

import pandas as pd
import numpy as np

#  --- 测试数据构造(可替换为你的实际数据)---
smalldf = pd.DataFrame({
    'RoadNo': ['A001', 'A001', 'A001', 'A002', 'A003'],
    'Range_FROM': [0, 1, 3, 0, 2],
    'Range_TO': [1, 3, 5, 2, 5],
    'values': [1.2, 3, np.nan, 2.1, np.nan]
})
largedf = pd.DataFrame({
    'RoadNo': ['A001','A001','A001','A001','A002','A002','A003','A003'],
    'B': [0.5, 1.2, 2.2, 3.5, 0.8, 1.5, 2.7, 4.1],
    'values': [1.2, 1.3, 1.6, 2.0, 1.9, 2.2, 1.6, 1.8]
})

# --- 核心逻辑 ---
# 先按RoadNo分组缓存largedf,减少重复筛选开销
large_group_map = {road: group for road, group in largedf.groupby('RoadNo')}

def match_min_val(row):
    # 无对应RoadNo分组直接返回原值
    if row['RoadNo'] not in large_group_map:
        return row['values']
    road_df = large_group_map[row['RoadNo']]
    # 筛选B落在[Range_FROM, Range_TO]区间内的记录
    match_mask = road_df['B'].between(row['Range_FROM'], row['Range_TO'])
    match_vals = road_df.loc[match_mask, 'values']
    # 匹配到记录就返回最小值,否则返回原值
    return match_vals.min() if not match_vals.empty else row['values']

# 直接覆盖values列:原有值大于匹配最小值就更新,NaN直接填充
smalldf['values'] = smalldf.apply(match_min_val, axis=1)

运行后结果完全符合规则示例:smalldf第二行原3更新为1.3,第三行NaN填充为1.6,其余行均取对应区间最小values。
如果数据量超过百万级,逐行apply性能不足,可以用pandasql库直接执行下方SQL逻辑,性能会有明显提升。


SQL 实现

用非等值关联+分组聚合先算出每个区间对应的最小值,再关联更新原表即可:

WITH interval_min_val AS (
    SELECT
        s.RoadNo,
        s.Range_FROM,
        s.Range_TO,
        MIN(l.values) AS match_min
    FROM smalldf s
    LEFT JOIN largedf l
        ON s.RoadNo = l.RoadNo
        AND l.B >= s.Range_FROM
        AND l.B <= s.Range_TO
    GROUP BY s.RoadNo, s.Range_FROM, s.Range_TO
)
UPDATE smalldf s
SET s.values = COALESCE(m.match_min, s.values)
FROM interval_min_val m
WHERE s.RoadNo = m.RoadNo
  AND s.Range_FROM = m.Range_FROM
  AND s.Range_TO = m.Range_TO;

内容的提问来源于stack exchange,提问作者HIM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:06:23