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

PySpark:如何使用另一个DataFrame的列过滤目标DataFrame?

解决方案:用另一DataFrame的列过滤Spark DataFrame

你原来的代码无法生效,是因为contains方法传入另一列时,Spark会尝试逐行两两比较DataFrame1和DataFrame2的对应行,而不是检查DataFrame1的列值是否包含DataFrame2列中的任意一个值,这不符合你的过滤需求。以下是三种可行的解决方法:

方法1:广播小DataFrame + Left Semi Join(推荐)

适合DataFrame2数据量小(比如你的10行)的场景,利用广播避免笛卡尔积,效率高:

from pyspark.sql.functions import broadcast

# 使用leftsemi join,只保留DataFrame1中能匹配的行,不会引入DataFrame2的列
contract_con = dataframe1.join(
    broadcast(dataframe2),
    dataframe1.name_of_column.contains(dataframe2.name_of_column),
    "leftsemi"
).distinct()  # 去重避免重复匹配的行
contract_con.show()

方法2:广播变量 + exists函数

通过exists函数检查DataFrame1的列值是否包含DataFrame2中的任意一个值:

from pyspark.sql.functions import broadcast, exists, col

# 广播DataFrame2的过滤列
broadcast_filter = broadcast(dataframe2.select("name_of_column").alias("filter_val"))

# 过滤出包含任意过滤值的行
contract_con = dataframe1.filter(
    exists(broadcast_filter, lambda x: col("name_of_column").contains(x.filter_val))
)
contract_con.show()

方法3:拼接正则表达式(适合极小规模数据)

把DataFrame2的列值拼成正则串,用rlike匹配(注意转义正则特殊字符):

from pyspark.sql.functions import col, regexp_replace

# 提取DataFrame2的过滤值并转义正则特殊字符
filter_values = [row.name_of_column for row in dataframe2.collect()]
escaped_values = [regexp_replace(val, r'([\.\*\+\?\|\(\)\[\]\{\}\\])', r'\\$1') for val in filter_values]
pattern = "|".join(escaped_values)

# 用rlike匹配任意子串
contract_con = dataframe1.filter(col("name_of_column").rlike(pattern))
contract_con.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:24:22