scala dataframe过滤字符串数组

时间:2017-04-06 18:57:14

标签: scala apache-spark scala-2.10 apache-spark-1.6

Spark 1.6.2 Scala 2.10

我想用一个字符串数组过滤spark数据帧列。

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

有人可以帮忙解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

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

你可以使用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")