3

Spark 1.6.2Scala 2.10在这里。

我想用字符串数组过滤火花数据框列。

val df1 = sc.parallelize(Seq((1, "L-00417"), (3, "L-00645"), (4, "L-99999"),(5, "L-00623"))).toDF("c1","c2")
+---+-------+
| c1|     c2|
+---+-------+
|  1|L-00417|
|  3|L-00645|
|  4|L-99999|
|  5|L-00623|
+---+-------+

val df2 = sc.parallelize(Seq((1, "L-1"), (3, "L-2"), (4, "L-3"),(5, "L-00623"))).toDF("c3","c4")

+---+-------+
| c3|     c4|
+---+-------+
|  1|    L-1|
|  3|    L-2|
|  4|    L-3|
|  5|L-00623|
+---+-------+

val c2List = df1.select("c2").as[String].collect()

df2.filter(not($"c4").contains(c2List)).show()`

我得到以下错误。

不支持的文字类型类 [Ljava.lang.String; [Ljava.lang.String;@5ce1739c

任何人都可以帮忙解决这个问题吗?

4

1 回答 1

3

首先,contains不适合,因为您正在寻找相反的关系 - 您想检查c2Listcontainsc4的值,而不是相反。

您可以使用isin- 它使用要匹配的值的“重复参数”(类似于 Java 的“varargs”),因此您希望“扩展”c2List为重复参数,这可以使用: _*运算符来完成:

df2.filter(not($"c4".isin(c2List: _*)))

或者,使用 Spark 1.6,您可以使用“左反连接”来连接两个数据帧并仅获取与以下df2值不匹配的值df1

df2.join(df1, $"c2" === $"c4", "leftanti")

与以前不同,此选项不限于df1小到可以收集的情况。

最后,如果您使用的是较早的 Spark 版本,您可以leftanti使用left连接和过滤器进行模仿:

df2.join(df1, $"c2" === $"c4", "left").filter($"c2".isNull).select("c3", "c4")
于 2017-04-06T19:17:41.917 回答