如何用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
相关产品推荐
相关产品推荐

