복붙노트

[HADOOP] ReduceByKey를 사용하여 값 목록 그룹화

HADOOP

ReduceByKey를 사용하여 값 목록 그룹화

키당 값 목록을 그룹화하고 다음과 같은 작업을 수행했습니다.

sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two"))).groupByKey().collect.foreach(println)

(red,CompactBuffer(zero, two))
(yellow,CompactBuffer(one))

그러나 Databricks에서 블로그 게시물을 발견했으며 큰 데이터 세트에 groupByKey를 사용하지 않는 것이 좋습니다.

GroupByKey 피하기

reduceByKey를 사용하여 동일한 결과를 얻을 수있는 방법이 있습니까?

나는 이것을 시도했지만 모든 값을 연결했다. 그건 그렇고, 내 경우에는 키와 값 모두 문자열 타입이다.

sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two"))).reduceByKey(_ ++ _).collect.foreach(println)

(red,zerotwo)
(yellow,one)

해결법

  1. ==============================

    1.aggregateByKey 사용 :

    aggregateByKey 사용 :

     sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two")))
    .aggregateByKey(ListBuffer.empty[String])(
            (numList, num) => {numList += num; numList},
             (numList1, numList2) => {numList1.appendAll(numList2); numList1})
    .mapValues(_.toList)
    .collect()
    
    scala> Array[(String, List[String])] = Array((yellow,List(one)), (red,List(zero, two)))
    

    가변적 인 데이터 세트 ListBuffer를 사용하는 이유에 대한이 링크 인 aggregateByKey에 대한 자세한 내용은이 답변을 참조하십시오.

    편집하다:

    reduceByKey를 사용하여 동일한 결과를 얻을 수있는 방법이 있습니까?

    위의 내용은 실제로 성능이 더 나쁩니다. 자세한 내용은 @ zero323의 주석을 참조하십시오.

  2. ==============================

    2.

    sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two")))
    .map(t => (t._1,List(t._2)))
    .reduceByKey(_:::_)
    .collect()
    
    Array[(String, List[String])] = Array((red,List(zero, two)), (yellow,List(one)))
    
  3. from https://stackoverflow.com/questions/37580303/using-reducebykey-to-group-list-of-values by cc-by-sa and MIT license