scala 内置函数
1,DataFrame API之中的内置函数进行了优化,不再返回一个结果,而是返回一个 Column对象,并且在并行作业之中
2, Column 可以用来在 DataFrame 的操作之中,比如 select filter和 groupBy计算
3, scala 内置函数分为 聚合函数,集合函数(例如,array_contains),日期时间函数,混合函数(例如:求随机值rand)等等
package day02
import org.apache.spark.sql.types.{StructType,StructField,StringType,IntegerType}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.sql.functions._ // 内置函数位置
object polymerization {
def main(args: Array[String]): Unit = {
val conf =new SparkConf().setAppName("function")
.setMaster("local[*]")
val sc = new SparkContext()
val sqlContext = new SQLContext(sc)
//使用 sqlContext 内置函数需要使用隐式转换
import sqlContext.implicits._
// 日期 与用户 id
val userAccessLog = Array(
"2016-12-1,1133,13",
"2016-12-1,1234,13",
"2016-12-2,1131,1",
"2016-12-1,1133") // 此处缺少一项
// // 对缺少的数据进行过滤
val filterUserSaleRDD = userAccessLog.filter(log =>
if(log.split(",").length==3) true else false
)
// 构造 RDD
val userAccessRDD= sc.makeRDD(filterUserSaleRDD,3)
// 将 普通的 RDD 转换成 Row 的 RDD
val userAccessLogRDD =userAccessRDD.map(
log => Row(log.split(",")(0),
log.split(",")(1).toInt)
)
// 构造 DataFrame 元数据
val structType = StructType(Array(
StructField("date", StringType, true),
StructField("userid", IntegerType, true)))
// 使用 sqlContext 创建 DataFrame
val userAccrssLogRowDF= sqlContext.createDataFrame(
userAccessLogRDD,structType)
// 按照 date 进行聚合(agg),每一组的 userid 进行去重,并统计总数(countDistinct)
// agg 里面是 单引号
userAccrssLogRowDF.groupBy("date")
.agg('date,countDistinct('userid))
.collect()
.foreach(println)
/*
[2016-12-1,2016-12-1,2] [2016-12-2,2016-12-2,1]
* */}}
spark 自定义函数:
1,spark UDF 是针对每行元素,返回一个输出
2,spark UDAF 是针对多行输入,进行聚合计算,返回一个输出,功能更加强大
package Day3
import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.{DataFrame, Row, SQLContext, SparkSession}
object UDF{
def main(args: Array[String]): Unit = {
val conf =new SparkConf().setAppName("UDAF").setMaster("local")
val sc = new SparkContext(conf)
val sqlcontext = new SQLContext(sc)
val name = Array("张三","李四","王五","孙二麻子","王五")
val nameRDD = sc.makeRDD(name,3)
val namerowRdd = nameRDD.map(name =>Row(name))
// 构造元数据
val structType = StructType(Array(StructField("name",StringType,true)))
val namesDF = sqlcontext.createDataFrame(namerowRdd,structType)
// 注册表
namesDF.registerTempTable("names")
//定义和注册自定义函数 strLen 参数为 : 函数名 与 匿名函数(求字符串的长度)
sqlcontext.udf.register("strLen",(str:String)=>str.length)
sqlcontext.sql("select name ,strLen(name) from names")
.collect().foreach(names=>println(names))
/*
[张三,2] [李四,2] [王五,2] [孙二麻子,4] [王五,2]
*/}}