Spark/Scala 작업을 하다 아래와 같은 에러가 발생했다.

Unsupported literal type class scala.collection.immutable.$colon$colon List(0, 1)





원인은 아래 문 isin 메소드 때문이다.


(아래 코드는 df1, df2라는 데이터 프레임에 대해 df1-df2를 하기 전에 
df1의 null 부분을 0으로 변경해, 쉽게 df1-df2(차집합)을 얻기 위한 코드이다)

import spark.implicits._

val validCode = List(0, 1)

var df1 =
Seq(
("1", "r1c2", null),
("2", "r2c2", new Integer(1)),
("3", "r2c2", new Integer(3))
).toDF("id", "c1", "c2")

val df2 =
Seq(
("1", "r1c2", new Integer(0)),
("2", "r2c2", new Integer(2))
).toDF("id", "c1", "c2")

df1 = df1.withColumn("c2", when($"c2".isin(validCode).isNull, 0) .otherwise($"c2"))
val df3 = df1.except(df2)
df3.show(5)



org.apache.spark.sql.Column.isin 메소드는 다음과 같다. Any 타입의 variable argument 타입을 추가해야 한다. 

def isin(list : scala.Any*)



그래서 에러 코드를 아래와 같이 변경하면.. 컴파일러가 인식하지 못한다.

isin(validCode) ->

isin(validCode:Any*)


이럴 때는 Any* 타입이 아니라 _* 으로 변경한다.


df1 = df1.withColumn("c2", 
         when($"c2".isin(validCode:_*).isNull, 0)
          .otherwise($"c2"))


코드는 잘 실행된다.


_*를 스칼라에서 Type Ascription(annotation으로 쉽게 표기하는 문법)에 필요한 문법으로서

Sugar Syntax로 말하기도 한다. 




isin(validCode:_*)

은 아래와 같이 사용해도 된다.

isInCollection(validCode)


Posted by '김용환'
,