内置函数(org.apache.spark.sql.funtions.scala)
一、常用内置函数:

1.聚合函数
approx_count_distinct/countDistinct: 计算某一列或几列不同元素的个数
avg: 平均数, count: 个数;
first: 首个元素, last:最后一个元素;
max/min, mean, sum, sumDistinct
var_pop: 总体方差, var_samp/variance 计算样本方差; stddev_pop, stddev_samp: 标准差
covar_pop, covar_samp 协方差,.corr 相关系数
kurtosis: 峰度; .skewness:偏度
2.集合函数
array_contains: 包含某个元素
array_distinct: 删除重复的元素
array_except 返回一个array 在第一个col 不在第二个col的元素
array_intersect(col1, col2) 交集4
array_max, array_min, array_position(col, value):第一次出现value的位置,从1开始
array_remove(col, element) 删除出现的元素
array_repeat(col, count): 创造一个数组,count为重复的个数
array_sort(col): 对数组进行排序
array_union(col1, col2), 合并操作
array_overlap, 判断是否有重叠
array_zip, 合并,类似于python的zip
reverse: 逆序; shuffle: 打乱; size, slice, sort_array
3.日期/时间函数
日期时间转换
unix_timestamp, from_unixtime, to_date, quarter, day, dayofyear, weekofyear, from_utc_timestamp, to_utc_timestamp
从日期时间中提取字段
year, month, dayofmonth, hour, minute, second
日期/时间计算
datediff, date_add, date_sub, add_months, last_day, next_day, months_between
获取当前时间等
current_date, current_timestamp, trunc, date_format
4.数学函数
abs, acros, asin, atan, atan2, bin, cbrt, ceil, conv, cos, sosh, exp, expm1, factorial, floor, hex, hypot, log, log10, log1p, log2, pmod, pow, rint, round, shiftLeft, shiftRight, shiftRightUnsigned, signum, sin, sinh, sqrt, tan, tanh, toDegrees, toRadians, unhex
5.混合函数
array, bitwiseNOT, callUDF, coalesce, crc32, greatest, if, inputFileName, isNaN, isnotnull, isnull, least, lit, md5, monotonicallyIncreasingId, nanvl, negate, not, rand, randn, sha, sha1, sparkPartitionId, struct, when
6.字符串函数
字符串分割,大小写转化,删除首尾空白, 正则表达式匹配
ltrim, rtrim, trim
ascii, base64, unbase64, decode, encode, format_string
repeat, reverse
instr(str, substr): 第一次出现的位置; locate(substr, str, pos=1)
字符拼接:concat, concat_ws
分割,子串: split, substring, substring_index
isnan, isnull, nanvl(col1, col2): 返回col1, 如果col1不为nan, 否则返回col2
lower, upper
7.窗口函数
cumeDist, denseRank, lag, lead, ntile, percentRank, rank, rowNumber
作用:分组,对一个组执行函数,这里面最常用的函数是rowNumber,我们可以用它来分组取topN
二、内置函数的使用
案例一:
object InnerFunctionDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("InnerFunctionDemo").master("local[*]").getOrCreate()
import spark.implicits._
val sc = spark.sparkContext
//模拟用户访问日志信息
val accessLog = Array(
"2016-12-27,001",
"2016-12-27,001",
"2016-12-27,002",
"2016-12-28,003",
"2016-12-28,004",
"2016-12-28,002",
"2016-12-28,002",
"2016-12-28,001"
)
//定义DataFrame的结构
val schema = StructType(Array(
StructField("day", StringType),
StructField("userId", IntegerType, true)
))
//根据集合数据生成RDD
val rdd = sc.parallelize(accessLog).map(x => x.split(",")).map(x => Row(x(0), x(1).toInt))
//根据数据以及Schema信息生成DataFrame
val df = spark.createDataFrame(rdd,schema)
df.printSchema()
df.show()
//导入Spark SQL内置的函数
import org.apache.spark.sql.functions._
//求每天所有的访问量(pv)
df.groupBy(df("day")).agg(count(df("userId")).as("pv")).show()
//求每天的去重访问量(uv)
df.groupBy(df("day")).agg(countDistinct(df("userId")).alias("v")).show()
}
}


案例二:
object InnerFunctionDemo2 {
case class Student(id: Int, name: String, gender: String, age: Int)
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("InnerFunctionDemo2").master("local[*]").getOrCreate()
val sc = spark.sparkContext
import spark.implicits._
val stuDF: DataFrame = Seq(
Student(1001, "zhangsan", "F", 20),
Student(1002, "lisi", "M", 16),
Student(1003, "wangwu", "M", 21),
Student(1004, "zhaoliu", "F", 21),
Student(1005, "zhouqi", "M", 22),
Student(1006, "qianba", "M", 19),
Student(1007, "liuliu", "F", 23)
).toDF()
stuDF.printSchema()
stuDF.show()
//导入Spark SQL内置的函数
import org.apache.spark.sql.functions._
stuDF.groupBy(stuDF("gender")).agg(count(stuDF("id"))).show()
stuDF.groupBy(stuDF("gender")).agg(max(stuDF("age"))).show()
stuDF.groupBy(stuDF("gender")).agg(min(stuDF("age"))).show()
stuDF.groupBy(stuDF("gender")).agg("age"->"max","age"->"min","age"->"avg","id"->"count").show()
// select * from table group by gender,age
stuDF.groupBy("gender","age").count().show()
}
}



自定义函数
步骤
1、定义函数
2、注册函数
SparkSession.udf.register():只在sql()中有效
functions.udf():对DataFrame API均有效
3、函数调用
案例
需求:用户行为喜好个数统计
输入数据格式:

输出数据格式:

创建一个hobbies.txt文件
alice jogging,Coding,cooking
lina travel,dance
代码实现
object SparkUDFDemo {
case class Hobbies(name:String,hobbies:String)
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("SparkUDFDemo").master("local[*]").getOrCreate()
//需要手动导入一个隐式转换,否则RDD无法转换成DF
import spark.implicits._
val sc = spark.sparkContext
val rdd = sc.textFile("in/hobbies.txt")
val df = rdd.map(x=>x.split("\t")).map(x=> Hobbies(x(0),x(1))).toDF()
df.printSchema()
df.show()
df.registerTempTable("hobbies")
//注册自定义函数,注意是匿名函数
spark.udf.register("hobby_num", (v:String) => v.split(",").size)
val frame = spark.sql("select name,hobbies,hobby_num(hobbies) as hobnum from hobbies")
frame.show()
}
}

补充内容:(udf,udaf,udtf之间的区别)
1、UDF:用户定义(普通)函数,只对单行数值产生作用;
继承UDF类,添加方法 evaluate()
/**
* @function 自定义UDF统计最小值
* @author John
*
*/
public class Min extends UDF {
public Double evaluate(Double a, Double b) {
if (a == null)
a = 0.0;
if (b == null)
b = 0.0;
if (a >= b) {
return b;
} else {
return a;
}
}
}
2、UDAF:User- Defined Aggregation Funcation;用户定义聚合函数,可对多行数据产生作用;等同与SQL中常用的SUM(),AVG(),也是聚合函数;
聚合函数使用:
SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500
ORDER BY SUM(sales);
键字HAVING总要放在GROUP BY之后,ORDER BY之前
UDAF实现有简单与通用两种方式:
- a. 简单UDAF因为使用Java反射导致性能损失,而且有些特性不能使用,已经被弃用了;
- b. 另一种涉及两个类:AbstractGenericUDAFResolver、GenericUDAFEvaluator;
继承UDAFResolver类,重写 getEvaluator() 方法;
继承GenericUDAFEvaluator类,生成实例给getEvaluator();
在GenericUDAFEvaluator类中,重写init()、iterate()、terminatePartial()、merge()、terminate()方法
参考:
hive udaf开发入门和运行过程详解
Hive UDAF开发详解
3.UDTF:User-Defined Table-Generating Functions,用户定义表生成函数,用来解决输入一行输出多行;
继承GenericUDTF类,重写initialize(返回输出行信息:列个数,类型), process, close三方法;
参考:
hive中UDTF编写和使用
hive0.13的udtf使用例子
4、其它
删除临时函数 drop temporary function toUpper;
本文详细介绍了Spark SQL中的内置函数,包括聚合、集合、日期时间、数学、混合、字符串和窗口函数,并提供了使用示例。同时,讲解了自定义函数(UDF、UDAF、UDTF)的创建、注册与调用,以及它们在数据处理中的应用,帮助理解Spark SQL函数的全面功能。
Spark SQL函数内置函数、自定义函数&spm=1001.2101.3001.5002&articleId=109736818&d=1&t=3&u=5a306b91c31e4c2eba05ae9a2d0cb5e8)
740

被折叠的 条评论
为什么被折叠?



