더북(TheBook)

5.1.5 DataFrame을 RDD로 변환

 

지난 5.1.1절에서는 RDD에서 DataFrame을 생성하는 방법을 소개했다. 여기서는 반대 방향으로 변환하는 방법을 알아본다. DataFrame은 RDD에 기반하기 때문에 DataFrame에서 RDD를 가져오는 것은 크게 복잡하지 않다. 다음과 같이 DataFramerdd 필드로 하부 RDD에 접근할 수 있다(이 rdd 필드의 평가 또한 지연(lazily evaluated)된다).

scala> val postsRdd = postsDf.rdd
postsRdd: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = ...

 

결과로 반환된 RDD는 org.apache.spark.sql.Row 타입의 요소로 구성된다(5.1.1절 stringToRow 함수에서 DataFrame 스키마를 지정하고 RDD를 DataFrame으로 변환하는 데 사용했던 Row 클래스다). Row 클래스는 칼럼 번호로 해당 칼럼 값을 가져올 수 있는 다양한 get* 함수[getString(index), getInt(index), getMap(index) 등]를 제공한다. 또 mkString(delimiter) 함수를 사용해 각 로우를 손쉽게 문자열로 만들 수 있다(스칼라 시퀀스의 mkString 함수와 흡사하다).

DataFrame 데이터와 파티션을 map이나 flatMap, mapPartitions 변환 연산자 등으로 매핑하면 실제 매핑 작업은 하부 RDD에서 실행된다. 그러므로 변환 연산의 결과 또한 새로운 DataFrame이 아니라 새로운 RDD가 된다. 4장에서 설명한 변환 연산자의 모든 내용이 DataFrame 변환 연산에도 동일하게 적용되며, 변환 연산자에 Row 객체를 처리하는 함수를 전달해야 한다는 제약 사항이 추가된다.

DataFrame의 변환 연산자는 DataFrame 스키마(즉, RDD 스키마)를 변경할 수 있다. 다시 말해 칼럼 순서나 개수, 타입을 변경할 수 있다. 또는 RDD의 Row 객체를 다른 타입으로 변환할 수도 있다. 하지만 타입을 변경한 RDD를 다시 DataFrame으로 변환하는 과정은 자동화할 수 없다. 변환 연산자가 DataFrame 스키마를 변경하지 않았다면 DataFrame의 이전 스키마를 그대로 사용해 새 DataFrame을 생성할 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.