PySpark | SparkSQL函数 | SparkSQL运行流程


传送门:


一、SparkSQL函数定义

1. SparkSQL 定义UDF函数

1.1 UDF函数的创建

  无论Hive还是SparkSQL分析处理数据时,往往需要使用函数,SparkSQL模块本身自带很多实现公共功能的函数,在pyspark.sql.functions中。SparkSQL与Hive一样支持定义函数:UDF和UDAF,尤其是UDF函数在实际项目中使用最为广泛。回顾Hive中自定义函数有三种类型:

  • 第一种:UDF (User-Defined-Function)函数
    一对一的关系,输入一个值经过函数以后输出一个值;
    在Hive中继承UDF类,方法名称为evaluate,返回值不能为void,其实就是实现一个方法;
  • 第二种:UDAF (User-Defined Aggregation Function)聚合函数
    多对一的关系,输入多个值输出一个值,通常与groupBy联合使用;
  • 第三种:UDTF (User-Defined Table-Generating Functions)函数
    —对多的关系,输入一个值输出多个值(一行变为多行);
    用户自定义生成函数,有点像flatMap

  在SparkSQL中,目前仅仅支持UDF函数和UDAF函数。目前Python仅支持UDF。SparkSQL定义UDF函数有两种方式:
方式一:sparksession.udf.register()
注册的UDF可以用于DSL和SQL。返回值用于DSL风格,传参内给的名字用于SQL风格。

方式1语法:
udf对象 = sparksession.udf.register(参数1,参数2,参数3)
参数1:UDF名称,可用于SQL风格
参数2:被注册成UDF的方法名
参数3:声明UDF的返回值类型
udf对象: 返回值对象,是一个UDF对象,可用于DSL风格
#!usr/bin/env python
# -*- coding:utf-8 -*-

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StringType, IntegerType
import pandas as pd
from pyspark.sql import functions as F

if __name__ == '__main__':
    # 0.构建SparkSession执行环境入口对象
    spark = SparkSession.builder. \
        appName('test'). \
        master('local[*]'). \
        config("spark.sql.shuffle.partitions", 2). \
        getOrCreate()

    sc = spark.sparkContext

    # 构建RDD
    rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7]).map(lambda x: [x])
    df = rdd.toDF(['num'])


    # TODO 1:方式1:sparksession.udf.register(),DSL和SQL风格均可以使用
    # UDF的处理函数
    def num_ride_10(num):
        return num * 10
    # 参数1:注册的UDF名称,这UDF名称可以用于SQL风格
    # 参数2:UDF的处理逻辑,是一个单独的方法
    # 参数3:UDF的返回值类型
    # 注意:UDF注册时候,会声明返回值类型,并且UDF的真实返回值一定要和声明的返回值一致
    # 返回值对象:这是一个UDF对象,既可以用于DSL语法
    # 当前这种方式定义的UDF,可以通过参数1的名称用于SQL风格,通过返回值对象用于DSL风格
    udf2 = spark.udf.register('udf1', num_ride_10, IntegerType())

    # SQL风格中使用
    # selectExpr以SELECT的表达式执行,
    # select方法,接受普通的字符串字段名,或者返回值是Column对象的计算
    df.selectExpr('udf1(num)').show()

    # DSL风格中使用
    # 返回值UDF对象,如果作为方法使用,传入的参数一定是Column对象。
    df.select(udf2(df['num'])).show()
+---------+
|udf1(num)|
+---------+
|       10|
|       20|
|       30|
|       40|
|       50|
|       60|
|       70|
+---------+

+---------+
|udf1(num)|
+---------+
|       10|
|       20|
|       30|
|       40|
|       50|
|       60|
|       70|
+---------+

方式二:pyspark.sql.functions.udf
仅能用于DSL风格

方式2语法:
udf对象 = F.udf(参数1, 参数2)
参数1:被注册成UDF的方法名
参数2:声明UDF的返回值类型
udf对象: 返回值对象,是一个UDF对象,可用于DSL风格
#!usr/bin/env python
# -*- coding:utf-8 -*-

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StringType, IntegerType
import pandas as pd
from pyspark.sql import functions as F

if __name__ == '__main__':
    # 0.构建SparkSession执行环境入口对象
    spark = SparkSession.builder. \
        appName('test'). \
        master('local[*]'). \
        config("spark.sql.shuffle.partitions", 2). \
        getOrCreate()

    sc = spark.sparkContext

    # 构建RDD
    rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7]).map(lambda x: [x])
    df = rdd.toDF(['num'])

    def num_ride_10(num):
        return num * 10

    # TODO 2 :方式2注册:pyspark.sql.functions.udf,仅能用于SQL风格
    udf3 = F.udf(num_ride_10, IntegerType())
    df.select(udf3(df['num'])).show()
+----------------+
|num_ride_10(num)|
+----------------+
|              10|
|              20|
|              30|
|              40|
|              50|
|              60|
|              70|
+----------------+

使用UDF两种方式的注册均可以。唯一需要注意的就是:返回值类型—定要有合适的类型来声明。

  • 返回int可以用IntergerType
  • 返回值小数,可以用FolatType或者DoubleType
  • 返回数组list可用ArrayType描述
  • 返回字典可用StructType描述

这些Spark内置的数据类型均存储在:pyspark.sql.types包中。

1.2 注册返回值是数组类型的UDF

  注册一个ArrayType(数字\list)类型的返回值UDF。

注意:数组或者list类型,可以使用spark的 ArrayType来描述即可。
注意:声明ArrayType要类似这样: ArrayType(StringType( ) ),在ArrayType中传入数组内的数据类型

# coding:utf8
import time

from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StringType, IntegerType, ArrayType
import pandas as pd
from pyspark.sql import functions as F


if __name__ == '__main__':
    # 0. 构建执行环境入口对象SparkSession
    spark = SparkSession.builder.\
        appName("test").\
        master("local[*]").\
        config("spark.sql.shuffle.partitions"
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幼稚的人呐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值