2017-04-06 144 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'的好處 - 請參閱編輯答案。 –