Spark SQL内置函数应用

7 篇文章 0 订阅
[b]简单说明[/b]
使用Spark SQL中的内置函数对数据进行分析,Spark SQL API不同的是,DataFrame中的内置函数操作的结果返回一个Column对象,而DataFrame天生就是“A distributed collection of data organized into named columns”,这就为数据的复杂分析建立了坚实的基础并提供了极大的方便性,例如说,我们在操作DataFrame的方法中可以随时调用内置函数进行业务需要的处理,这之于我们构建附件的业务逻辑而言是可以极大的减少不必须的时间消耗(基本上就是实际模型的映射),让我们聚焦在数据分析上,这对于提高工程师的生产力而言是非常有价值的;
Spark 1.5.x开始提供了大量的内置函数,例如agg:
def agg(aggExpr: (String, String), aggExprs: (String, String)*): DataFrame = {
groupBy().agg(aggExpr, aggExprs : _*)
}

还有max,mean,min,sum,ave,explode,size,sort_array,day,to_date,abs,acros,asin,atan等
总体而言,内置函数包含了五大基本类型:
1.聚合函数,例如countDistinct,sumDistinct等;
2.集合函数,例如sort_array,explode等;
3.日期,时间函数,例如hour,quarter,next_day等;
4.数学函数,例如asin,atan,sqrt,tan,round等;
5.开窗函数,例如rowNumber等;
6.字符串函数,例如concat,format_number,rexexp_extract(正则)等;
7.其他函数,isNaN,sha,randn,callUDF等;


package com.imf.spark.sql

import org.apache.spark.sql.{SQLContext, Row}
import org.apache.spark.sql.types.{StructType, IntegerType, StringType, StructField}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.functions._
/**
* Description:使用Spark SQL中的内置函数对数据进行分析
* Author:lujinyong168
* Date:2016/4/14 21:09
*/
object SparkSQLAgg {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
conf.setAppName("SparkSQLAgg for scala")
conf.setMaster("local")

val sc = new SparkContext(conf)
// val sqlContext = new HiveContext(sc)//构建上下文
val sqlContext = new SQLContext(sc)//构建上下文

//要使用Spark SQL 的内置函数,就一定要导入SQLContext下的隐式转换
import sqlContext.implicits._
/**
* 简单模拟电商访问的数据
*/
val userData = Array(
"2016-04-15,1001,http://spark.apache.org,1000",
"2016-04-15,1001,http://hadoop.apache.org,1001",
"2016-04-15,1002,http://fink.apache.org,1002",
"2016-04-16,1003,http://kafka.apache.org,1020",
"2016-04-16,1004,http://spark.apache.org,1010",
"2016-04-16,1002,http://hive.apache.org,1200",
"2016-04-16,1001,http://parquet.apache.org,1500",
"2016-04-16,1001,http://spark.apache.org,1800"
)

val userDataRDD = sc.parallelize(userData)//生成RDD分布式集合对象


/**
* 根据业务需要对数据进行预处理生成DataFrame,要想把RDD转换成DataFrame,需要先把RDD中的元素类型变成Row类型
* 与此同时要提供DataFrame中的Columns的元素信息描述
*/
val userDataRDDRow = userDataRDD.map(row=> {val splited = row.split(",");Row(splited(0),splited(1).toInt,splited(2),splited(3).toInt)})
val structTypes = StructType(Array(
StructField("date",StringType,true),
StructField("id",IntegerType,true),
StructField("url",StringType,true),
StructField("amount",IntegerType,true)
))
val userDataDF = sqlContext.createDataFrame(userDataRDDRow,structTypes)

/**
* 使用Spark SQL提供的内置函数对DataFrame进行操作,特别注意:内置函数生成的Column对象且自动进行CG(code generation)
* 所有的内置函数操作结果都会返回具体的列
* DataFrame中的列可以动态增长
*/
//userDataDF.groupBy("date").agg('date,countDistinct('id)).show()
// userDataDF.groupBy("date").agg('date,countDistinct('id)).map(row => Row(row(1),row(2))).collect.foreach(println)//数据量比较大时不能用collect
userDataDF.groupBy("date").agg('date,sum('amount)).show()//对销售额统计

}
}


[b]执行结果[/b]

userDataDF.groupBy("date").agg('date,countDistinct('id)).show()
返回的结果:
+----------+----------+---------+
| date| date|count(id)|
+----------+----------+---------+
|2016-04-15|2016-04-15| 2|
|2016-04-16|2016-04-16| 4|
+----------+----------+---------+
userDataDF.groupBy("date").agg('date,countDistinct('id)).map(row => Row(row(1),row(2))).collect.foreach(println)//数据量比较大时不能用collect
返回的结果:
[2016-04-15,2]
[2016-04-16,4]
userDataDF.groupBy("date").agg('date,sum('amount)).show()//对销售额统计
返回的结果:
+----------+----------+-----------+
| date| date|sum(amount)|
+----------+----------+-----------+
|2016-04-15|2016-04-15| 3003|
|2016-04-16|2016-04-16| 6530|
+----------+----------+-----------+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值