2017-04-06 89 views
0

Spark 1.6.2Scala 2.10 here。scala数据框过滤器数组过滤器

我想用字符串数组过滤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

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

回答

2

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

您可以使用isin为 - 它使用值的“反复论证”(类似于Java的“可变参数”)相匹配,所以你要“扩大” c2List成反复论证,这是可以做到使用: _*操作:

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

或者,星火1.6,你可以使用一个“左反加入”,加入这两个dataframes和df2未在df1匹配值只得到值:

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

与前面不同,此选项不限于df1足够小以便收集的情况。

最后,如果你正在使用较早版本的Spark,您可以使用left加入immitate leftanti和过滤器:

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

leftanti我认为它不是在星火1.6.2版本 – Ramesh

+0

df2.filter(不($“c4”.isin(c2List:_ *)))这适用于小集合。让我检查一下我在c​​2List中实际使用的1500个值。 – Ramesh

+0

关于'leftanti'的好处 - 请参阅编辑答案。 –