博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spark DataFrame的groupBy vs groupByKey
阅读量:6270 次
发布时间:2019-06-22

本文共 2521 字,大约阅读时间需要 8 分钟。

在使用Spark SQL的过程中,经常会用到groupBy这个函数进行一些统计工作。但是会发现除了groupBy外,还有一个groupByKey(注意RDD也有一个groupByKey,而这里的groupByKey是DataFrame的)。这个groupByKey引起了我的好奇,那我们就到源码里面一探究竟吧。

所用spark版本:spark2.1.0

先从使用的角度来说,

groupBy:groupBy类似于传统SQL语言中的group by子语句,但比较不同的是groupBy()可以带多个列名,对多个列进行group。比如想根据"id"和"name"进行groupBy的话可以

df.goupBy("id","name")

groupBy返回的类型是RelationalGroupedDataset。

groupByKey:groupByKey则更加灵活,可以根据用户自己对列的组合来进行groupBy,比如上面的那个例子,根据"id"和"name"进行groupBy,使用groupByKey可以这样。

//同前面的goupBy效果是一样的,但返回的类型是不一样的df..toDF("id","name").goupByKey(row =>{    row.getString(0) + row.getString(1)})

但和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 `Dataset.groupBy`. * * 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 Spark 1.x. * * @since 2.0.0 */@InterfaceStability.Stableclass 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 = sparkSession.sessionState.executePlan(withGroupingKey)    new KeyValueGroupedDataset(      encoderFor[K],      encoderFor[T],      executed,      inputPlan.output,      withGroupingKey.newColumns)  }

可以发现最后生成和返回的类是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.Evolvingclass KeyValueGroupedDataset[K, V] private[sql](

可以发现groupByKey还处于实验阶段。它是希望可以由用户自己来实现groupBy的规则,而不像groupBy()一样,需要被列属性所束缚。

通过groupByKey用户可以按照自己的需求来进行grouping。

总而言之,groupByKey虽然提供了更加灵活的处理grouping的方式,但groupByKey后返回的类是KeyValueGroupedDataset,它里面所提供的操作接口也不如groupBy返回的RelationalGroupedDataset所提供的接口丰富。除非真的有一些特殊的grouping操作,否则还是使用groupBy吧。

转载于:https://www.cnblogs.com/listenfwind/p/9860228.html

你可能感兴趣的文章
hdu 4472
查看>>
oracle存储过程中is和as区别
查看>>
windows 2003 群集
查看>>
几个gcc的扩展功能
查看>>
Spark一个简单案例
查看>>
关于结构体占用空间大小总结(#pragma pack的使用)
查看>>
通过浏览器查看nginx服务器状态配置方法
查看>>
shell简介
查看>>
android 使用WebView 支持播放优酷视频,土豆视频
查看>>
怎么用secureCRT连接Linux
查看>>
C# 使用WinRar命令压缩和解压缩
查看>>
linux学习笔记一----------文件相关操作
查看>>
Mono for Android 优势与劣势
查看>>
服务器端开发技术
查看>>
Python3中urllib详细使用方法(header,代理,超时,认证,异常处理)
查看>>
ajax提交多个对象,使用序列化表单和FormData
查看>>
深入分析由前序和中序重构二叉树问题
查看>>
leetcode 题解 || Valid Parentheses 问题
查看>>
将图片转成base64字符串并在JSP页面显示的Java代码
查看>>
什么是WeakHashMap--转
查看>>