scala dataframe 过滤字符串数组

scala dataframe filter array of strings

Spark 1.6.2Scala 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()`

我遇到了以下错误。

Unsupported literal type class [Ljava.lang.String; [Ljava.lang.String;@5ce1739c

谁能帮忙解决这个问题?

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

您可以为此使用 isin - 它使用 "repeated argument"(类似于 Java 的 "varargs")的值进行匹配,因此您需要将 "expand" c2List 转换为重复参数,这可以使用 : _* 运算符来完成:

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

或者,在 Spark 1.6 中,您可以使用 "left anti join",连接两个数据帧并仅获取值df2df1 中的值不匹配:

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

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

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

df2.join(df1, $"c2" === $"c4", "left").filter($"c2".isNull).select("c3", "c4")