PySpark列名相似DataFrame差异行提取存储方案
问题背景
需要对两个PySpark DataFrame的计数列做一致性校验,两类不匹配场景的行需要分别存储到独立的差异DataFrame中:
- 某DataFrame的行在另一DataFrame中不存在
- 关联键匹配的行,计数值不相等
已验证对应SQL逻辑可输出正确结果,但参照SQL编写PySpark代码时抛出解析异常,无法正常运行。
错误原因
原代码存在3个核心问题:
- Join语法错误:PySpark中
join方法的on参数如果传入列相等判断表达式,不能用字符串形式写A.a_row = B.b_row,这种写法会被解析为按名为A.a_row = B.b_row的同名列做USING连接,自然找不到对应列抛出解析异常。 - 过滤条件笔误:原代码写的
A.counting != A.counting是恒假判断,完全无法实现“两边计数值不相等”的过滤逻辑;第二个Join的过滤条件逻辑写反,和预期SQL判断规则不一致。 - 列名不匹配:给出的PySpark DataFrame中计数字段名是
count,不是SQL里的counting,直接用counting会触发列不存在错误。
实现方案
提供两种可直接运行的实现,结果完全对齐SQL逻辑:
方案1:Left Join写法(和SQL逻辑一一对应)
先给DataFrame设置别名避免列名歧义,再按关联条件做左连接,最后过滤差异行:
# 注册别名避免列名冲突 a = A.alias("a") b = B.alias("b") # 提取A侧差异行 A_diff = a.join( b, on = a.a_row == b.b_row, how = "left" ).where( (b.count.isNull()) | (a.count != b.count) ).select( a.a_row, a.count.alias("counting") ) # 提取B侧差异行 B_diff = b.join( a, on = a.a_row == b.b_row, how = "left" ).where( (a.count.isNull()) | (b.count != a.count) ).select( b.b_row, b.count.alias("counting") )
方案2:exceptAll差集写法(性能更优)
先把两个DataFrame的列名统一,再直接用PySpark内置的exceptAll方法取差集,该方法会保留重复行,完全匹配计数校验场景,相比Join写法减少一次shuffle,运行效率更高:
# 统一两个DataFrame的字段名 a_std = A.selectExpr("a_row as row_content", "count as counting") b_std = B.selectExpr("b_row as row_content", "count as counting") # 直接取差集得到两侧差异 A_diff = a_std.exceptAll(b_std) B_diff = b_std.exceptAll(a_std)
运行结果
两种方案得到的结果完全一致:
- A_diff 结果:
+--------------------------------------------+--------+ |row_content |counting| +--------------------------------------------+--------+ |xyz|def|2022-05-27|09:05:17.023|13432 |2 | |lkj|def|2022-05-07|09:05:17.023|14362 |3 | +--------------------------------------------+--------+
- B_diff 结果:
+--------------------------------------------+--------+ |row_content |counting| +--------------------------------------------+--------+ |xyz|def|2022-05-27|09:05:17.023|13432 |1 | |poi|def|2022-05-27|09:50:17.023|450545 |2 | +--------------------------------------------+--------+
注:原描述中贴出的SQL预期结果里,两个xyz行的计数值写反了,上述结果和表内实际数据、SQL逻辑完全匹配。
内容的提问来源于stack exchange,提问作者Saad Hasan
相关产品推荐
相关产品推荐

