簡體   English   中英

具有復合值的RDD鍵值對

[英]RDD Key-Value pair with composite value

我這里,我需要計算在該狀態下(在該州的所有城市的人口的總和)的每一個國家和人口的城市的名單玩具數據集數據

我想使用RDD而不使用groupByKey和聯接。 到目前為止,我的方法:

在這種方法中,我使用了2個單獨的鍵值對並將它們結合在一起。

val rdd1=inputRdd.map(x=>(x._1,x._3.toInt))
val rdd2=inputRdd.map(x=>(x._1,x._2))
val popn_sum=rdd1.reduceByKey(_+_)
val list_cities=rdd2.reduceByKey(_++_)
popn_sum.join(list_cities).collect()

是否只有1個鍵值對且沒有任何聯接就可以獲得相同的輸出。 我創建了一個新的鍵值對,但是我不知道如何使用帶有RDD的aggregateByKey或reduceByKey來獲得相同的輸出:

val rdd3=inputRdd.map(x=>(x._1,(List(x._2),x._3))) 

我是新手,並想學習獲得此輸出的最佳方法。

Array((B,(12,List(B1, B2))), (A,(6,List(A1, A2, A3))), (C,(8,List(C1, C2))))

提前致謝

如果您的inputRdd是類型

inputRdd: org.apache.spark.rdd.RDD[(String, String, Int)]

然后,您只需使用一個reduceByKey作為

inputRdd.map(x => (x._1, (List(x._2), x._3.toInt))).reduceByKey((x, y) => (x._1 ++ y._1, x._2+y._2))

你可以用aggregateByKey作為

inputRdd.map(x => (x._1, (List(x._2), x._3.toInt))).aggregateByKey((List.empty[String], 0))((x, y) => (x._1 ++ y._1, x._2+y._2), (x, y) => (x._1 ++ y._1, x._2+y._2))

DataFrame方式

更好的方法是使用數據框方式。 您只需應用.toDF("state", "city", "population")即可將rdd轉換為數據幀.toDF("state", "city", "population")這應該會給您

+-----+----+----------+
|state|city|population|
+-----+----+----------+
|A    |A1  |1         |
|B    |B1  |2         |
|C    |C1  |3         |
|A    |A2  |2         |
|A    |A3  |3         |
|B    |B2  |10        |
|C    |C2  |5         |
+-----+----+----------+

之后,您可以只使用groupBy ,並應用collect_list並將內置的聚合函數sum

import org.apache.spark.sql.functions._
inputDf.groupBy("state").agg(collect_list(col("city")).as("cityList"), sum("population").as("sumPopulation"))

這應該給你

+-----+------------+-------------+
|state|cityList    |sumPopulation|
+-----+------------+-------------+
|B    |[B1, B2]    |12           |
|C    |[C1, C2]    |8            |
|A    |[A1, A2, A3]|6            |
+-----+------------+-------------+

Dataset幾乎相同,但具有附加的類型安全性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM