Scala DataFrame筛选字符串数组

3

这里使用的是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()`

我遇到了以下错误:

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

请问有人能帮忙解决这个问题吗?

1个回答

3
首先,contains 不适用于您正在查找的相反关系-您想检查 c2List 是否包含 c4 的值,而不是反过来。您可以使用 isin - 它使用要匹配的值的“重复参数”(类似于Java的“varargs”),因此您需要将 c2List “展开”为一个重复参数,可以使用 : _* 运算符来完成:
df2.filter(not($"c4".isin(c2List: _*)))

另外,在Spark 1.6中,您可以使用"left anti join",将两个数据框连接起来,并仅获取df2中未匹配到df1的值:

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

与之前不同,这个选项不仅限于df1够小而可以进行收集的情况。
最后,如果您使用早期的Spark版本,您可以使用left连接和过滤器来模拟leftanti
df2.join(df1, $"c2" === $"c4", "left").filter($"c2".isNull).select("c3", "c4")

2
左反,我认为它不在Spark 1.6.2版本中。 - Ramesh
df2.filter(not($"c4".isin(c2List: _*))) 这个在小数据集上运行良好。让我来检查一下实际上我在 c2List 中有 1500 个值的情况。 - Ramesh
你好Tzach,谢谢。第一种方法可行。df2.filter(not($"c4".isin(c2List: _*))) - Ramesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接