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

基于Python Polars实现多条件DataFrame的类Vlookup操作

批量匹配Excel表格并添加SortInfo字段

问题背景

需要将"分拣信息表"中的SortInfo字段匹配到待匹配表格的对应行,匹配规则基于街道、邮编、城市的完全匹配,同时门牌号需符合分拣信息表中指定的范围与奇偶条件。

分拣信息表结构

streetHnr_fromHnr_tohnr_condPostcodeCitySortInfo
Hasel68049082OsnbOS1-01
Hasel15149083OsnbOS1-02
Mosel46249084MunstMU1-01

hnr_cond说明:0=门牌号全部匹配,1=仅奇数匹配,2=仅偶数匹配

待匹配表格结构

streetHnrPostcodeCity
Hasel749082Osnb
Mosel449084Munst

此前尝试的单行处理代码

原代码仅能处理单条数据,无法批量处理待匹配表格的所有行:

import polars as pl

xlsx_file = "Path/to/Sortinfo-file.xlsx"
df = pl.read_excel(xlsx_file)

searched_nr = 3
searched_str = "Mosel"
searched_postc = 49088
searched_city = "Osnbr"

filtered_df = df.filter(
    (searched_nr >= df['Hnr_from']) &
    (searched_nr <= df['Hnr_to']) &
    (((searched_nr % 2 == 0) & (df['hnr_cond'] == '2')) |
     ((searched_nr % 2 == 1) & (df['hnr_cond'] == '1')) |
     (df['hnr_cond'] == '0')) &
    (searched_str == df['street']) &
    (searched_postc == df['Postcode']) &
    (searched_city == df['City'])
)

SortInfo = None
if not filtered_df.is_empty():
    # 原代码存在笔误,应取SortInfo而非bezirk
    SortInfo = filtered_df.to_pandas()['SortInfo'].iloc[0]

print(SortInfo)

待匹配表格加载代码

xlsx_file = "path/to/other-file.xlsx"
df_searched = pl.read_excel(xlsx_file)

searched_number = df_seached['Hnr']
searched_street = df_seached['street']
searched_postcode = df_seached['Postcode']
searched_City = df_searched['City']

期望结果

最终需得到包含SortInfo字段的匹配后表格:

streetHnrPostcodeCitySortInfo
Hasel749082OsnbOS1-01
Mosel449084MunstMU1-01

解决方案

使用Polars的条件连接实现批量匹配,效率更高且逻辑清晰:

import polars as pl

# 加载两个表格
df_sortinfo = pl.read_excel("Path/to/Sortinfo-file.xlsx")
df_searched = pl.read_excel("path/to/other-file.xlsx")

# 执行条件连接
result_df = df_searched.join(
    df_sortinfo,
    # 先匹配基础字段:街道、邮编、城市
    on=["street", "Postcode", "City"],
    # 添加门牌号范围与奇偶判断条件
    condition=(
        (pl.col("Hnr") >= pl.col("Hnr_from")) &
        (pl.col("Hnr") <= pl.col("Hnr_to")) &
        pl.when(pl.col("hnr_cond") == 0)
        .then(True)
        .when(pl.col("hnr_cond") == 1)
        .then(pl.col("Hnr") % 2 == 1)
        .when(pl.col("hnr_cond") == 2)
        .then(pl.col("Hnr") % 2 == 0)
        .otherwise(False)
    ),
    # 保留待匹配表所有行,未匹配到的SortInfo为null
    how="left"
).select(
    # 按期望结果排序字段
    "street", "Hnr", "Postcode", "City", "SortInfo"
)

# 输出结果
print(result_df)

代码说明

  1. 条件连接:通过join的condition参数同时校验基础匹配字段和门牌号规则,避免交叉连接的性能浪费。
  2. 奇偶判断优化:用pl.when语法清晰处理hnr_cond的三种场景,比多或条件更易维护。
  3. 左连接逻辑:how="left"确保待匹配表的所有行都被保留,无匹配时SortInfo字段为null。
  4. 字段整理:最后通过select调整字段顺序,与期望结果完全对齐。

注:若分拣信息表中存在多条匹配同一行的记录,需根据实际需求添加unique()或调整连接逻辑,确保每行仅保留一个SortInfo。

内容的提问来源于stack exchange,提问作者Yannik Brüggemann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 16:47:14