SparkDataFrame的groupByvsgroupByKey
在使⽤ Spark SQL 的过程中,经常会⽤到 groupBy 这个函数进⾏⼀些统计⼯作。但是会发现除了 groupBy 外,还有⼀个
groupByKey(**注意RDD 也有⼀个 groupByKey,⽽这⾥的 groupByKey 是 DataFrame 的 **) 。这个 groupByKey 引起了我的好奇,那我们就到源码⾥⾯⼀探究竟吧。
所⽤ spark 版本:spark 2.1.0
先从使⽤的⾓度来说,
**groupBy:**groupBy类似于传统SQL语⾔中的group by⼦语句,但⽐较不同的是groupBy()可以带多个列名,对多个列进⾏group。⽐如想根据 “id” 和 “name” 进⾏ groupBy 的话可以
groupBy返回的类型是RelationalGroupedDataset。
**groupByKey:**groupByKey则更加灵活,可以根据⽤户⾃⼰对列的组合来进⾏groupBy,⽐如上⾯的那个例⼦,根据 “id” 和“name” 进⾏ groupBy,使⽤groupByKey可以这样。
//同前⾯的goupBy效果是⼀样的,但返回的类型是不⼀样的
groupby是什么函数
})
但和groupBy不同的是groupByKey返回的类型是KeyValueGroupedDataset。
下⾯来看看这两个⽅法的实现有何区别。
groupBy
def groupBy(cols: Column*): RelationalGroupedDataset = {
RelationalGroupedDataset(toDF(), cols.map(_.expr), RelationalGroupedDataset.GroupByType)
}
最终会去新建⼀个RelationalGroupedDataset,⽽这个⽅法提供count(),max(),agg(),等⽅法。值得⼀提的是,这个类在spark1.x的时候类名为“GroupedData”。看看类中的注释吧
/**
* A set of methods for aggregations on a `DataFrame`, created by `upBy`.
*
* The main method is the agg function, which has multiple variants. This class also contains
* convenience some first order statistics such as mean, sum for convenience.
*
* This class was named `GroupedData` in
*
* @since 2.0.0
*/
@InterfaceStability.Stable
class RelationalGroupedDataset protected[sql](
groupByKey
@Experimental
@InterfaceStability.Evolving
def groupByKey[K: Encoder](func: T => K): KeyValueGroupedDataset[K, T] = {
val inputPlan = logicalPlan
val withGroupingKey = AppendColumns(func, inputPlan)
val executed = utePlan(withGroupingKey)
new KeyValueGroupedDataset(
encoderFor[K],
encoderFor[T],
executed,
inputPlan.output,
}
可以发现最后⽣成和返回的类是KeyValueGroupedDataset。这是dataset的⼦类,表⽰聚合过之后的dataset。
我们再看看这个类中的注释吧
/**
* :: Experimental ::
* A [[Dataset]] has been logically grouped by a user specified grouping key.  Users should not
* construct a [[KeyValueGroupedDataset]] directly, but should instead call `groupByKey` on
* an existing [[Dataset]].
*
* @since 2.0.0
*/
@Experimental
@InterfaceStability.Evolving
class KeyValueGroupedDataset[K, V] private[sql](
可以发现 groupByKey 还处于实验阶段。它是希望可以由⽤户⾃⼰来实现 groupBy 的规则,⽽不像 groupBy() ⼀样,需要被列属性所束缚。
通过 groupByKey ⽤户可以按照⾃⼰的需求来进⾏ grouping 。
总⽽⾔之,groupByKey虽然提供了更加灵活的处理 grouping 的⽅式,但 groupByKey 后返回的类是 KeyValueGroupedDataset ,它⾥⾯所提供的操作接⼝也不如 groupBy 返回的 RelationalGroupedDataset 所提供的接⼝丰富。除⾮真的有⼀些特殊的 grouping 操作,否则还是使⽤ groupBy 吧。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。