2017-04-06 13 views
0

스파크 1.6.2스칼라 2.10 여기.스칼라 데이터 프레임 필터 문자열 배열

스파크 데이터 프레임 열을 문자열 배열로 필터링하고 싶습니다.

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이 적합하지 않습니다. c2Listc4의 값이 포함되어 있는지 확인하고 다른 방법으로는 확인하지 않으려합니다.

일치하는 값의 "반복 인수"(Java의 "varargs"와 유사)를 사용하는 isin을 사용할 수 있습니다. 따라서 반복 인수로 c2List을 "확장"해야합니다. : _* 연산자를 사용 : 스파크 1.6, 또는

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

당신은 두 dataframes에 가입하고 df1의 값과 일치하지 않습니다 df2 만 값을 얻기 위해, "왼쪽 반은 참여"를 사용할 수 있습니다 :

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

이전과 달리,이 옵션은 df1이 수집 될만큼 충분히 작은 경우에만 제한되지 않습니다.

이전 스파크 버전을 사용하는 경우 마지막으로는, 당신이 left join을 사용하여 leftanti을 immitate를 할 수

및 필터 :

나는 그것하지 스파크에서 1.6.2 버전
+2

(안 ($ "c4".isin (c2List : _ *))) 이것은 작은 세트에서 작동했습니다. 실제로 c2List에있는 1500 개의 값 집합을 확인하겠습니다. – Ramesh

+0

df2.filter 생각 leftanti

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

+0

'leftanti'에 대한 좋은 지적 - 편집 된 답변보기. –