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)