아파치 스파크 RDD flatMap

IT 위키

Apache Spark의 flatMap 연산은 RDD의 각 요소를 변환하여 0개 이상의 요소를 포함하는 새로운 RDD를 생성하는 변환 연산이다. 일반적인 map 연산과 달리, 각 입력 요소에서 다수의 출력 요소를 생성할 수 있다.

1 개요[편집 | 원본 편집]

`flatMap`은 입력 데이터를 변환하면서 하나의 입력 요소가 여러 개의 출력 요소로 매핑될 수 있도록 하는 기능을 제공한다. 이는 리스트를 펼치는(flattening) 동작과 결합되어, 중첩된 데이터 구조를 단순화하는 데 유용하다.

2 flatMap과 map의 차이[편집 | 원본 편집]

`map과 flatMap의 주요 차이점은 다음과 같다.

  • map`: 입력 요소 하나당 하나의 출력 요소를 생성한다.
  • flatMap`: 입력 요소 하나당 0개 이상의 출력 요소를 생성할 수 있으며, 결과를 단일 리스트로 평탄화(flattens) 한다.

예제:

val rdd = sc.parallelize(Array("Hello World", "Apache Spark"))

// map을 사용한 경우 (배열이 중첩됨)
val mapRDD = rdd.map(line => line.split(" "))
mapRDD.collect().foreach(println)

// 출력 결과
// [Ljava.lang.String;@7a62b72f
// [Ljava.lang.String;@3d04a2d6

// flatMap을 사용한 경우 (평탄화됨)
val flatMapRDD = rdd.flatMap(line => line.split(" "))
flatMapRDD.collect().foreach(println)

// 출력 결과
// Hello
// World
// Apache
// Spark

3 flatMap 예제[편집 | 원본 편집]

3.1 리스트 펼치기[편집 | 원본 편집]

다중 리스트가 포함된 데이터를 평탄화할 때 사용된다.

val data = sc.parallelize(Seq(List(1, 2, 3), List(4, 5), List(6)))
val flatMappedRDD = data.flatMap(x => x)
flatMappedRDD.collect().foreach(println)

// 출력 결과
// 1
// 2
// 3
// 4
// 5
// 6

3.2 텍스트 데이터를 단어 단위로 변환[편집 | 원본 편집]

한 줄의 문장을 단어 리스트로 변환할 때 유용하다.

val textRDD = sc.parallelize(Array("Scala is great", "Spark is fast"))
val wordsRDD = textRDD.flatMap(line => line.split(" "))
wordsRDD.collect().foreach(println)

// 출력 결과
// Scala
// is
// great
// Spark
// is
// fast

3.3 JSON 데이터 처리[편집 | 원본 편집]

JSON 데이터에서 특정 필드를 추출하는 경우에도 활용할 수 있다.

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.Row

val spark = SparkSession.builder.appName("FlatMapExample").getOrCreate()
val sc = spark.sparkContext

val jsonRDD = sc.parallelize(Seq(
  """{"name": "Alice", "hobbies": ["Reading", "Swimming"]}""",
  """{"name": "Bob", "hobbies": ["Cycling"]}"""
))

import scala.util.parsing.json.JSON

val hobbiesRDD = jsonRDD.flatMap(row => {
  val parsed = JSON.parseFull(row)
  parsed match {
    case Some(map: Map[String, Any]) => map.get("hobbies") match {
      case Some(hobbies: List[String]) => hobbies
      case _ => Nil
    }
    case _ => Nil
  }
})

hobbiesRDD.collect().foreach(println)

// 출력 결과
// Reading
// Swimming
// Cycling

4 flatMap 사용 시 주의점[편집 | 원본 편집]

  • flatMap`은 입력 요소가 `Iterable` 타입을 반환해야 하며, 내부 요소가 자동으로 평탄화된다.
  • 데이터가 많을 경우 변환 후 RDD의 크기가 급격히 증가할 수 있으므로 메모리 사용량을 고려해야 한다.
  • map`과의 차이를 이해하고 적절한 경우에 사용해야 한다.

같이 보기[편집 | 원본 편집]