【SparkSQL】SparkSQL的UDF及分析

SparkSQL的UDF及分析

【模块一:DSL的使用】

知识点1:【理解】DSL开发使用API函数

  • 目标理解DSL开发中API函数的使用

  • 实施

    • DSL方式:类似于RDD中调用算子的方式,实现对数据的处理

    • DSL函数

      • API函数:类似于RDD中的算子,用法基本一致,但是支持的算子不多,支持一些缓存调整分区、简单的算子
      • SQL函数:将SQL语句中的关键词转换成函数:select、groupBy、orderBy、where、limit
    • API函数类RDD算子

      • 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函数
      类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-数据处理:读取
  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用SparkSQLHive API,可以通过以下步骤实现用户自定义函数(UDF)、聚合函数(UDAF)和表生成函数(UDTF): 1. 编写自定义函数的代码,例如: ``` // UDF def myUDF(str: String): Int = { str.length } // UDAF class MyUDAF extends UserDefinedAggregateFunction { override def inputSchema: StructType = StructType(StructField("value", StringType) :: Nil) override def bufferSchema: StructType = StructType(StructField("count", IntegerType) :: Nil) override def dataType: DataType = IntegerType override def deterministic: Boolean = true override def initialize(buffer: MutableAggregationBuffer): Unit = { buffer(0) = 0 } override def update(buffer: MutableAggregationBuffer, input: Row): Unit = { buffer(0) = buffer.getInt(0) + input.getString(0).length } override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = { buffer1(0) = buffer1.getInt(0) + buffer2.getInt(0) } override def evaluate(buffer: Row): Any = { buffer.getInt(0) } } // UDTF class MyUDTF extends GenericUDTF { override def initialize(args: Array[ConstantObjectInspector]): StructObjectInspector = { // 初始化代码 } override def process(args: Array[DeferedObject]): Unit = { // 处理代码 } override def close(): Unit = { // 关闭代码 } } ``` 2. 将自定义函数注册到SparkSQLHive中,例如: ``` // SparkSQL中注册UDF spark.udf.register("myUDF", myUDF _) // Hive中注册UDF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDF AS 'com.example.MyUDF'") // Hive中注册UDAF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDAF AS 'com.example.MyUDAF'") // Hive中注册UDTF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDTF AS 'com.example.MyUDTF'") ``` 3. 在SQL语句中使用自定义函数,例如: ``` -- 使用SparkSQL中的UDF SELECT myUDF(name) FROM users -- 使用Hive中的UDF SELECT myUDF(name) FROM users -- 使用Hive中的UDAF SELECT myUDAF(name) FROM users GROUP BY age -- 使用Hive中的UDTF SELECT explode(myUDTF(name)) FROM users ``` 以上就是使用SparkSQLHive API实现用户自定义函数(UDF、UDAF、UDTF)的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a1迪三火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值