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

如何用Pythonic方式在PySpark中实现多条件LIKE ANY过滤?

PySpark中实现SQL LIKE ANY的Pythonic方案

需求背景

想要在PySpark中用最Pythonic的方式实现SQL里的LIKE ANY逻辑,原SQL代码如下:

select
  *
from
  <catalog>.<schema>.<table>
where
  <column> like any (<constraint_1>,<constraint_2>,<constraint_3>)

尝试过几种方法但都不尽人意:

  • 直接用like配合拼接的正则字符串无效,因为like不支持正则语法
  • 用or直接连接约束只会匹配第一个条件
  • 手动拼接多个like条件会因约束过多导致代码冗长

解决方案

方法1:用functools.reduce合并多个like条件

利用Python的functools.reduce批量合并多个like过滤条件,代码简洁且支持任意数量的约束:

from functools import reduce
import pyspark.sql.functions as F

# 定义约束列表
constraints = ["%abc%", "%def%", "%ghi%"]
column_name = "your_column"

sdf = spark.read.table("<catalog>.<schema>.<table>")
# 用reduce把多个like条件通过逻辑或(|)合并
filter_condition = reduce(
    lambda cond, pattern: cond | F.col(column_name).like(pattern),
    constraints,
    F.lit(False)  # 初始设为False,确保第一个条件能正常叠加
)

sdf_filtered = sdf.filter(filter_condition)

方法2:转换为正则表达式用rlike匹配

把LIKE的通配符转换为正则语法,再用rlike实现多模式匹配:

import pyspark.sql.functions as F

constraints = ["%abc%", "%def%", "_xyz"]
column_name = "your_column"

# 转换like通配符为正则规则:%替换为.*,_替换为.
regex_patterns = [
    pattern.replace("%", ".*").replace("_", ".")
    for pattern in constraints
]
# 用|拼接成正则表达式,括号确保匹配优先级
final_regex = "(" + "|".join(regex_patterns) + ")"

sdf = spark.read.table("<catalog>.<schema>.<table>")
sdf_filtered = sdf.filter(F.col(column_name).rlike(final_regex))

方法3:直接使用SQL表达式(简洁但稍欠Pythonic)

如果想贴近原SQL写法,可以用expr直接编写LIKE ANY逻辑:

import pyspark.sql.functions as F

constraints = ["%abc%", "%def%", "%ghi%"]
column_name = "your_column"

# 将约束转换为SQL字符串格式的列表
constraints_str = ", ".join(f"'{p}'" for p in constraints)
filter_expr = f"{column_name} like any ({constraints_str})"

sdf = spark.read.table("<catalog>.<schema>.<table>")
sdf_filtered = sdf.filter(F.expr(filter_expr))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:31:13