gpt4 book ai didi

scala - Spark join 产生错误的结果

转载 作者:行者123 更新时间:2023-12-03 14:44:32 25 4
gpt4 key购买 nike

在可能提交错误之前在此处展示。我正在使用 Spark 1.6.0。

这是我正在处理的问题的简化版本。我过滤了一个表,然后我尝试对该子集和主表进行左外连接,匹配所有列。

我在主表中只有 2 行,在过滤表中只有 1 行。我期望结果表只有来自子集的单行。

scala> val b = Seq(("a", "b", 1), ("a", "b", 2)).toDF("a", "b", "c")
b: org.apache.spark.sql.DataFrame = [a: string, b: string, c: int]

scala> val a = b.where("c = 1").withColumnRenamed("a", "filta").withColumnRenamed("b", "filtb")
a: org.apache.spark.sql.DataFrame = [filta: string, filtb: string, c: int]

scala> a.join(b, $"filta" <=> $"a" and $"filtb" <=> $"b" and a("c") <=> b("c"), "left_outer").show
+-----+-----+---+---+---+---+
|filta|filtb| c| a| b| c|
+-----+-----+---+---+---+---+
| a| b| 1| a| b| 1|
| a| b| 1| a| b| 2|
+-----+-----+---+---+---+---+

我完全没想到会是这样的结果。我期待第一行,但不是第二行。我怀疑这是空安全的平等,所以我没有尝试。
scala> a.join(b, $"filta" === $"a" and $"filtb" === $"b" and a("c") === b("c"), "left_outer").show
16/03/21 12:50:00 WARN Column: Constructing trivially true equals predicate, 'c#18232 = c#18232'. Perhaps you need to use aliases.
+-----+-----+---+---+---+---+
|filta|filtb| c| a| b| c|
+-----+-----+---+---+---+---+
| a| b| 1| a| b| 1|
+-----+-----+---+---+---+---+

好的,这就是我预期的结果,但后来我对警告产生了怀疑。这里有一个单独的 StackOverflow 问题来处理该警告: Spark SQL performing carthesian join instead of inner join

所以我创建了一个避免警告的新列。
scala> a.withColumn("newc", $"c").join(b, $"filta" === $"a" and $"filtb" === $"b" and $"newc" === b("c"), "left_outer").show
+-----+-----+---+----+---+---+---+
|filta|filtb| c|newc| a| b| c|
+-----+-----+---+----+---+---+---+
| a| b| 1| 1| a| b| 1|
| a| b| 1| 1| a| b| 2|
+-----+-----+---+----+---+---+---+

但是现在结果又错了!
我有很多空安全的平等检查,并且警告不是致命的,所以我没有看到处理/解决这个问题的明确途径。

该行为是错误还是预期的行为?如果预期,为什么?

最佳答案

如果您想要预期的行为,请使用 join关于名字:

val b = Seq(("a", "b", 1), ("a", "b", 2)).toDF("a", "b", "c")
val a = b.where("c = 1")

a.join(b, Seq("a", "b", "c")).show
// +---+---+---+
// | a| b| c|
// +---+---+---+
// | a| b| 1|
// +---+---+---+

或别名:
val aa = a.alias("a")
val bb = b.alias("b")

aa.join(bb, $"a.a" === $"b.a" && $"a.b" === $"b.b" && $"a.c" === $"b.c")

您可以使用 <=>还有:
aa.join(bb, $"a.a" <=> $"b.a" && $"a.b" <=> $"b.b" && $"a.c" <=> $"b.c")

据我所知,一段时间以来一直有一个简单的平等的特殊情况。这就是为什么尽管有警告但您仍能获得正确结果的原因。

第二个行为看起来确实像是一个与您仍然拥有 a.c 的事实相关的错误。在您的数据中。好像是在 b.c之前被下游采摘的并且评估条件实际上是 a.newc = a.c .
val expr = $"filta" === $"a" and $"filtb" === $"b" and $"newc" === $"c"
a.withColumnRenamed("c", "newc").join(b, expr, "left_outer")

关于scala - Spark join 产生错误的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36131942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com