如何使用Polars实现基于跟踪表的拍卖表多条件灵活匹配查询?
Polars DataFrame实现动态多条件拍卖数据匹配
完整解决方案代码
import polars as pl import math # 示例数据 auctiondata = {"ItemId": [15331, 15332, 15333, 15213, 15331, 15213], "AuctionId": [2084868458, 2085008809, 2087827052, 2087835700, 2087827999, 2087827997], "RealmName": ['Gehennas', 'Gehennas', 'Mograine', 'Lakeshire', 'Gehennas', 'Bloodfang'], "Stat0": ['+3 Stamina', '+2 Intelelct', '+3 Stamina', '+3 Agility', '+3 Stamina', '+3 Stamina'], "Stat1": ['+3 Agility', '+3 Stamina', '+3 Intellect', '+3 Stamina', '+3 Agility', '+3 Agility'], "Stat2": ['', '', '', '','',''], "Stat3": ['', '', '', '','',''], "Stat4": ['', '', '', '','',''], "buyoutgold": ['40', '', '', '', '120','']} trackingdata = {"ItemId": [15331, 15213, 15333], "RealmName": ['Gehennas', '', 'Mograine'], "Stat0": ['+3 Stamina', '+3 Stamina', '+3 Stamina'], "Stat1": ['+3 Agility', '+3 Agility', '+3 Intellect'], "Stat2": ['', '', ''], "Stat3": ['', '', ''], "Stat4": ['', '', ''], "buyoutgold": ['50', '', '']} auctiondf = pl.DataFrame(auctiondata) trackingdf = pl.DataFrame(trackingdata) # 1. 处理Stat字段:转为非空属性的集合(忽略顺序) stat_cols = [f"Stat{i}" for i in range(5)] auctiondf = auctiondf.with_columns( pl.struct(stat_cols).apply(lambda x: set(v for v in x.values() if v != "")).alias("stat_set") ) trackingdf = trackingdf.with_columns( pl.struct(stat_cols).apply(lambda x: set(v for v in x.values() if v != "")).alias("stat_set") ) # 2. 处理buyoutgold:转为数值类型,空值填充为无穷大(实现空值无限制) auctiondf = auctiondf.with_columns( pl.col("buyoutgold").str.to_integer(default=None).fill_null(math.inf).alias("buyoutgold_num") ) trackingdf = trackingdf.with_columns( pl.col("buyoutgold").str.to_integer(default=None).fill_null(math.inf).alias("buyoutgold_num") ) # 3. 执行匹配:按ItemId关联后过滤多条件 matched_df = auctiondf.join(trackingdf, on="ItemId", how="inner", suffix="_track") matched_df = matched_df.filter( # RealmName条件:非空时匹配,空时跳过 (pl.col("RealmName_track") == "") | (pl.col("RealmName") == pl.col("RealmName_track")) & # Stat集合包含匹配(忽略顺序) pl.col("stat_set").apply(lambda s: s.issuperset(pl.col("stat_set_track"))) & # buyoutgold上限控制 pl.col("buyoutgold_num") <= pl.col("buyoutgold_num_track") ) # 4. 整理结果:保留原始列并去重 result_df = matched_df.select(auctiondf.columns).unique() print("匹配结果:") print(result_df)
关键步骤说明
Stat字段无序匹配处理
将每行的Stat0-Stat4转换为过滤空值后的集合,利用集合的issuperset方法,直接判断拍卖数据的属性是否包含跟踪条件指定的属性组合,天然实现顺序无关的匹配逻辑。buyoutgold空值兼容
将字符串类型的金价转为整数,空值填充为无穷大。当跟踪条件的金价为空时,拍卖数据的任何金价都满足<= 无穷大的判断,完美适配“空值无限制”的需求。动态多条件过滤
先通过ItemId关联两张表,再逐一处理可选条件:- 若
RealmName非空则强制匹配,为空则跳过该条件; - 验证属性集合包含关系;
- 验证金价不超过上限。
- 若
结果去重
同一拍卖记录可能匹配多个跟踪条件,通过unique()方法确保结果中每条拍卖记录只出现一次。
内容的提问来源于stack exchange,提问作者Shamatix
相关产品推荐
相关产品推荐

