SparkSQL的UDF及分析
【模块一:DSL的使用】
知识点1:【理解】DSL开发使用API函数
-
目标:理解DSL开发中API函数的使用
-
实施
-
DSL方式:类似于RDD中调用算子的方式,实现对数据的处理
-
DSL函数
- API函数:类似于RDD中的算子,用法基本一致,但是支持的算子不多,支持一些缓存、调整分区、简单的算子
- SQL函数:将SQL语句中的关键词转换成函数:select、groupBy、orderBy、where、limit
-
API函数
- count:统计行数
- collect:将DataFrame转换成一个数组
- take:取DataFrame中前N行的数据
- first:取DataFrame中第一行的数据
- head:默认取DataFrame中第一行的数据,可以指定返回前N行的数据
- tail:可以指定返回后N行的数据
- foreach:对DataFrame中每条数据进行处理,没有返回值
- foreachPartition:对DataFrame中每个分区数据进行处理,没有返回值
- distinct:对DataFrame中每条数据进行去重处理
- union/unionAll:实现两个DataFrame的合并
- coalesce/repartition:调整DataFrame的分区数
- cache/persist:对DataFrame进行缓存
- unpersist:取消DataFrame的缓存
- columns:返回DataFrame中的所有列名
- schema:返回DataFrame中Schema的信息
- rdd:返回DataFrame中的数据放入RDD中
- printSchema:打印DataFrame的Schema信息
-
完整代码
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import re from pyspark import StorageLevel from pyspark.sql import SparkSession if __name__ == '__main__': # todo:0-设置系统环境变量 os.environ['JAVA_HOME'] = '/export/server/jdk' os.environ['HADOOP_HOME'] = '/export/server/hadoop' os.environ['PYSPARK_PYTHON'] = '/export/server/anaconda3/bin/python3' os.environ['PYSPARK_DRIVER_PYTHON'] = '/export/server/anaconda3/bin/python3' # todo:1-构建SparkContext spark = SparkSession \ .builder \ .appName("MovieApp") \ .master("local[2]") \ .config("spark.sql.shuffle.partitions", 2) \ .getOrCreate() # todo:2-数据处理:读取、转换、保存 people_df = spark.read.json("../datas/resources/people.json") # 基本算子:count/collect/take/first/head/tail/foreach/foreachPartition/distinct/union/unionAll/coalesce/repartition count = people_df.count() print(f"总共有:{ count}行") collect = people_df.collect() print(f"转换成列表以后的内容是:{ collect}") take = people_df.take(2) print(f"前三行的内容是:{ take}") first = people_df.first() print(f"前一行的内容是:{ first}") head = people_df.head(2) print(f"表格的前两行的内容是:{ head}") tail = people_df.tail(1) print(f"最后一行的内容是:{ tail}") people_df.foreach(lambda row: print(row)) people_df.foreachPartition(lambda part: print(*part)) print("union的结果") people_df_other = spark.read.json("../datas/resources/people.json") people_df.union(people_df_other).show() print("unionAll的结果") people_df.unionAll(people_df_other).show() print("distinct的结果") people_df.unionAll(people_df_other).distinct().show() print(f"原来的分区数:{ people_df.rdd.getNumPartitions()}") print(f"减少后分区数:{ people_df.coalesce(1).rdd.getNumPartitions()}") print(f"增大后分区数:{ people_df.repartition(4).rdd.getNumPartitions()}") # 持久化算子 people_df.cache() people_df.persist(StorageLevel.MEMORY_AND_DISK_2) people_df.unpersist(blocking=True) # 其他算子 columns = people_df.columns print(f"所有列的名称:{ columns}") schema = people_df.schema print(f"所有列的信息:{ schema}") rdd = people_df.rdd rdd.foreach(lambda x: print(x)) people_df.printSchema() # todo:3-关闭SparkContext spark.stop()
-
-
小结:理解DSL开发中API函数的使用
知识点2:【理解】DSL开发使用SQL函数
-
目标:理解DSL开发中SQL函数的使用
-
实施
-
设计:将SQL中的语法转换成了函数,通过使用函数的方式来使用SQL语法
-
SQL函数
# 1、选择函数select:选取某些列或者某些函数表达式的值 def select(self, *cols: Union[Column, str]) -> DataFrame # 2、过滤函数filter/where:设置过滤条件,类似SQL中WHERE语句 def filter(self, condition: Union[Column, str]) -> DataFrame # 3、分组函数groupBy/rollup/cube:对某些字段分组,在进行聚合统计 def groupBy(self, *cols: Union[Column, str]) -> GroupedData # 4、聚合函数agg:通常与分组函数连用,使用一些count、max、sum等聚合函数操作 def agg(self, *exprs: Union[Column, Dict[str, str]]) -> DataFrame # 5、排序函数sort/orderBy:按照某写列的值进行排序(升序ASC或者降序DESC) def sort(self, *cols: Union[str, Column, List[Union[str, Column]]], ascending: Union[bool, List[bool]] = ...) -> DataFrame # 6、限制函数limit:获取前几条数据,类似RDD中take函数 def limit(self, num: int) -> DataFrame # 7、重命名函数withColumnRenamed:将某列的名称重新命名 def withColumnRenamed(self, existing: str, new: str) -> DataFrame # 8、删除函数drop:删除某些列 def drop(self, cols: Union[Column, str]) -> DataFrame # 9、增加列函数withColumn:当某列存在时替换值,不存在时添加此列 def withColumn(self, colName: str, col: Column) -> DataFrame
-
注意:在调用函数对列进行操作时,可以使用col或者column函数将字符串转换成一个列的对象
-
测试案例:将电影评分案例通过DSL SQL函数来实现
#!/usr/bin/env python # -*- coding: utf-8 -*- from pyspark.sql import SparkSession import os import re import pyspark.sql.functions as F """ ------------------------------------------------- Description : TODO:使用DSL实现统计评分次数最高的前10部的信息 SourceFile : 06.pyspark_sql_movie_case_dsl Author : Frank Date : 2022/7/23 ------------------------------------------------- """ if __name__ == '__main__': # todo:0-设置系统环境变量 os.environ['JAVA_HOME'] = '/export/server/jdk' os.environ['HADOOP_HOME'] = '/export/server/hadoop' os.environ['PYSPARK_PYTHON'] = '/export/server/anaconda3/bin/python3' os.environ['PYSPARK_DRIVER_PYTHON'] = '/export/server/anaconda3/bin/python3' # todo:1-构建SparkSession spark = SparkSession \ .builder \ .appName("SparkSQLAppName") \ .master("local[2]") \ .config("spark.sql.shuffle.partitions", 2) \ .getOrCreate() # 设置日志级别为WARN spark.sparkContext.setLogLevel("WARN") # todo:2-数据处理:读取
-