经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Spark » 查看文章
Spark DataFrame 的 groupBy vs groupByKey
来源:cnblogs  作者:zzzzMing  时间:2018/11/5 10:51:12  对本文有异议

在使用 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 的话可以

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

groupBy返回的类型是RelationalGroupedDataset。

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

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

但和groupBy不同的是groupByKey返回的类型是KeyValueGroupedDataset。

下面来看看这两个方法的实现有何区别。

groupBy
  1. def groupBy(cols: Column*): RelationalGroupedDataset = {
  2. RelationalGroupedDataset(toDF(), cols.map(_.expr), RelationalGroupedDataset.GroupByType)
  3. }

最终会去新建一个RelationalGroupedDataset,而这个方法提供count(),max(),agg(),等方法。值得一提的是,这个类在spark1.x的时候类名为“GroupedData”。看看类中的注释吧

  1. /**
  2. * A set of methods for aggregations on a `DataFrame`, created by `Dataset.groupBy`.
  3. *
  4. * The main method is the agg function, which has multiple variants. This class also contains
  5. * convenience some first order statistics such as mean, sum for convenience.
  6. *
  7. * This class was named `GroupedData` in Spark 1.x.
  8. *
  9. * @since 2.0.0
  10. */
  11. @InterfaceStability.Stable
  12. class RelationalGroupedDataset protected[sql](
groupByKey
  1. @Experimental
  2. @InterfaceStability.Evolving
  3. def groupByKey[K: Encoder](func: T => K): KeyValueGroupedDataset[K, T] = {
  4. val inputPlan = logicalPlan
  5. val withGroupingKey = AppendColumns(func, inputPlan)
  6. val executed = sparkSession.sessionState.executePlan(withGroupingKey)
  7. new KeyValueGroupedDataset(
  8. encoderFor[K],
  9. encoderFor[T],
  10. executed,
  11. inputPlan.output,
  12. withGroupingKey.newColumns)
  13. }

可以发现最后生成和返回的类是KeyValueGroupedDataset。这是dataset的子类,表示聚合过之后的dataset。
我们再看看这个类中的注释吧

  1. /**
  2. * :: Experimental ::
  3. * A [[Dataset]] has been logically grouped by a user specified grouping key. Users should not
  4. * construct a [[KeyValueGroupedDataset]] directly, but should instead call `groupByKey` on
  5. * an existing [[Dataset]].
  6. *
  7. * @since 2.0.0
  8. */
  9. @Experimental
  10. @InterfaceStability.Evolving
  11. class KeyValueGroupedDataset[K, V] private[sql](

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

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号