开发者学堂课程【大数据 Spark 2020版(知识精讲与实战演练)第三阶段:聚合操作_多维聚合_cube】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/690/detail/12092
聚合操作_多维聚合_cube
Cube
pmFinal.rollup( cols ="source, 'year)
.agg(avg( " pm) as "pm")
.sort( "source.asc_nulls_last,"year.asc_nulls_last)
.show()
问题:以上代码是按照 source,year 进行 rollup,假如改成 rollup(‘year,’source),二者结果一样吗?
结果不一样,依据:如果 rollup A,B,groupby 三次,分别是 groupby A B、groupby A、groupby null。如果 rollup B,A,groupby 也是三次,但是是 groupby B A、groupby B、groupby null。如果调换 A 和 B 的位置,在第二次 groupby 时出现分歧,二者结果不一样是因为 rollup 结果不均衡。
在 rollup A,B 中缺少的是 groupby B,因为 rollup 始终是以第一列为支点列进行滚动。
Cube 是对为了 rollup 进行弥补,假设在 rollup A,B 时,groupby
B 是有必要的,因为很多场景下 groupby B 确实是有必要的,要
对每一种组合来进行 groupby B,这时就应该使用 cube。Rollup
和 cube 是一样的,但 cube 是全排列。
cube 的功能和 rollup 是一样的,但也有区别,区别如下:
.rollup(A,B). sum
其结果集中会有三种数据形式:A B C ,A null C , null null C
不知道家发现没,结果集中没有对 B 列的聚合结果
.cube(A,B).sum
其结果集中会有四种数据形式: A B C , A null C , null null C , null
B
C
不知道大家发现没:比 rollup 的结果集中多了一个 null B C ,也就是
说, rollup 只会按照第一个列来进行组合聚合,但是 cube 会将全部
列组合聚合。
进入代码:
创建方法,将数据集拷贝进来
@Test
def cube(): unit = {
val schemaFinal = structType(
list(
structField( "source", stringType),
structField( "year", IntegerType) ,
structField("month", IntegerType),
structField( "day", IntegerType),
structField( "hour", IntegerType),
structField("season", IntegerType) ,
structField( "pm", DoubleType)
)
)
val pmFinal = spark.read
.schema( schemaFinal)
.option( "header", value = true)
.csv( path = "dataset/ pm_final,csv")
import org.apache. spark.sql.functions._
pmFinal.cube(cols ="source,'year)
//对排序结果进行聚合 agg
.agg(avg( " pm) as "pm")
.sort( 'source.asc_nulls_last,"year.asc_nulls_last)
/进行升序排序,null 放在最后
.show(
}
这个案例和之前案例不一样之处:算子不同,之前是 rollup,现在是
cube 以及结果集不同。
运行并查看结果集:
前四行数据是 dongsi 按照年份统计的 pm 值,us_post 也是按照
source,year 进行统计 pm 值。最下面几行 null 数据是按照年份
统计的 pm 值。
Cube 和 rollup 是一样的,只是 cube 的结果集是全排列的,每一种
情况都具备。