Scala中的aggregateByKey()函数

本文详细介绍了Scala中aggregateByKey函数的使用方法,包括其源码解读、功能介绍及实际应用场景。通过两个具体示例展示了如何利用该函数进行键值对的聚合操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.Scala中的aggregateByKey()函数

1.先看源码:

/**
   * Aggregate the values of each key, using given combine functions and a neutral "zero value".
   * This function can return a different result type, U, than the type of the values in this RDD,
   * V. Thus, we need one operation for merging a V into a U and one operation for merging two U's,
   * as in scala.TraversableOnce. The former operation is used for merging values within a
   * partition, and the latter is used for merging values between partitions. To avoid memory
   * allocation, both of these functions are allowed to modify and return their first argument
   * instead of creating a new U.
   */
  def aggregateByKey[U: ClassTag](zeroValue: U, numPartitions: Int)(seqOp: (U, V) => U,
      combOp: (U, U) => U): RDD[(K, U)] = self.withScope {
    aggregateByKey(zeroValue, new HashPartitioner(numPartitions))(seqOp, combOp)
  }

2.翻译:
对每个键进行聚合操作,使用给出的聚合函数和一个中性的“0”。aggregate()()函数能够返回一个不同的值类型—U,而不是RDD中的值类型-V。【注,这里的v指的是key-value形式中的value】因此,我们需要一种操作来合并V(value)作为U,同时需要另一种操作两两合并U(的value)。在scala中,TranversableOnce。第一种操作是用来将同一个分区中的值合并,第二种操作是将不同分区中的值合并。为了避免内存分配,这两种操作均被允许修改,并且返回他们的第一个参数,而非创建一个新的结果类型U。
3.样例1:

scala> val rdd = sc.parallelize(List((1,3),(1,2),(1,4),(2,3),(3,6),(3,8)),3)
rdd: org.apache.spark.rdd.RDD[(Int, Int)] = ParallelCollectionRDD[0] at parallelize at <console>:24

scala> val rdd1 = rdd.aggregateByKey(0)(math.max(_,_),_+_)
rdd1: org.apache.spark.rdd.RDD[(Int, Int)] = ShuffledRDD[3] at aggregateByKey at <console>:26

scala> rdd1.foreach(println)
(2,3)
(3,8)
(1,7)

样例2:

scala> val pairRDD = sc.parallelize(Array(("cat", 2), ("cat", 5),("mouse", 4), ("dog", 6)),2)
pairRDD: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[4] at parallelize at <console>:24

scala> val resultPair = pairRDD.aggregateByKey(0)(_+_,_+_)
resultPair: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[5] at aggregateByKey at <console>:26

scala> resultPair.foreach(println)
(mouse,4)
(dog,6)
(cat,7)

4.解释:
样例1:
这里有一个rdd,里面存放的是List,而List中存放的是map,即键值对,在这里的键值都是Int型的数字。

  • 分区内的操作是对相同的键的map取max,如果不是相同键,则保留。这里一个有三个分区,恰好每个分区存放两个map。在进行math.max(_,_)操作之后,其实就变成了这个样子:分区1:(1,3),分区2:(1,4)(2,3);分区3:(3,8)
  • 再进行第二轮操作—分区间的操作:对不同分区的相同键的值进行合并。然后得到的结果即是:(1,7)(2,3)(3,8)

样例2:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值