使用 '==' 比较器和使用带有 spark 的 .contains('val') 有啥区别?
Posted
技术标签:
【中文标题】使用 \'==\' 比较器和使用带有 spark 的 .contains(\'val\') 有啥区别?【英文标题】:What's the difference between using the '==' comparator and using .contains('val') with spark?使用 '==' 比较器和使用带有 spark 的 .contains('val') 有什么区别? 【发布时间】:2019-05-09 18:36:05 【问题描述】:我有一个通过将其他三个数据框连接在一起创建的数据框,我需要对其执行许多 sum case 语句。我发现 withcolumn() 函数可能是我的解决方案,但是当我对具有 char 的列进行比较时,当我使用 .contains() 或 '==' 时,会得到两个截然不同的数字。
下面的代码显示了两者的使用方式- 这是带有 .contains 的代码:
test_data.withColumn('NewCol', F.when((test_data.col1 == 'str') & ((test_data.col2.contains('X')) | (test_data.col2.contains('Y'))) ,1).otherwise(0)) \
.groupBy('KEY') \
.agg(F.sum('NewCol').alias('NewCol))
结果计数为 127470 行 > 0
这是带有比较器的代码:
test_data.withColumn('NewCol', F.when((test_data.col1 == 'str') & ((test_data.col2 == 'X') | (test_data.col2 == 'Y')) ,1).otherwise(0)) \
.groupBy('KEY') \
.agg(F.sum('NewCol').alias('NewCol))
结果计数为 531645 行 > 0。
如您所见,当使用比较器与 .contains() 时,具有 1 的行数要大得多。 .contains() 是在进行比较之前进行过滤,还是有其他原因导致数字大相径庭?
【问题讨论】:
==
是整个列的精确匹配,contains()
匹配一个子字符串。
您的括号分组在两个查询中不一样,这说明了很大的差异。
你能编辑或告诉我它们的不同之处吗?因为我看不出两者之间的区别在哪里。 '&' 之后的两个语句组合在一起作为 or 仅用于它们,而 '&' 之前的语句是单独的。所有这些都在它们应该在的 when 语句中分组。我错过了什么吗?谢谢!
@Barmar 这很有道理,但我认为它并不能真正解决我的问题。我正在使用的数据集有数亿个条目,我将其限制为仅一百万个用于测试。正在比较的列是仅包含一个字符的列。此列只有四个可能的字符之一,因此即使是这种情况,结果计数也应该相同,不是吗?
改变括号会改变匹配的逻辑,因为&&
和||
的优先级。
【参考方案1】:
== 匹配整个字符串 .contains() 搜索字符串以查找字符串 例子: “昨天”==“天”是假的 但 "昨天".Contains("day") 是真的
【讨论】:
这是有道理的,但它并不能解决我的问题,这可能是我措辞的错误?不过谢谢你的回答。正在比较的列是仅包含一个字符的列。此列只有四个可能的字符之一,因此即使是这种情况,结果计数也应该相同,不是吗?没有要比较的字符串,只有一个字符。 这并不能解释为什么使用==
的查询比使用更宽松的contains()
的查询返回更多 个结果。以上是关于使用 '==' 比较器和使用带有 spark 的 .contains('val') 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spark SQL 创建带有连接的 Hive 表时使用的引擎