• Spark权威指南读书笔记(三) 处理不同的数据类型


    Spark权威指南读书笔记(三) 处理不同的数据类型

    一、转换成Spark类型

    使用lit函数将原始类型转换为Spark类型

    image-20200810105248256

    二、处理布尔类型

    布尔语句由四个要素组成: and、or、true和false。

    scala中有一些关于 == 和 ===用法的特殊语义。在Spark中,如果想通过相等条件来进行过滤,应该使用 ===(等于) 或 =!=(不等于)符号,还可以使用not函数和equalTo方法实现。

    image-20200810114550866

    另一种方法是使用字符串形式的谓词表达式

    image-20200810145443163

    对于链式连接的方式, Spark会将所有过滤条件合并为一条语句,并同时执行这些过滤器,创建and语句。

    image-20200810150046291

    构建过滤列

    image-20200810150914477

    注:创建布尔表达式时,需注意空值处理否则易出现问题。可使用以下语句保证执行空值执行的等价测试。

    image-20200810152241370

    三、处理数值类型

    1.基础运算

    image-20200810153914066

    2.四舍五入

    使用round或bround函数进行四舍五入,round/bround支持某个精度级别的转换, 若恰好处于两数之间,则round函数会向上取整, bround函数向下取整。

    image-20200810165249402

    3.计算两列相关性(以Pearson系数为例)
    $$
    ho = frac{cov(X, Y)}{sigma x sigma y} = frac{E[(X-mu x)(Y - mu y)]}{sigma x sigma y} \
    r = frac{sum_{i = 1}^{n} (X_i - ar X)(Y_i - ar(Y) }{sqrt[]{sum_{i = 1}^n (X_i - ar X)^2} sqrt[]{sum_{i = 1}^n (Y_i - ar Y)^2}} \
    r = frac{1}{n-1} sum_ {i = 1} ^ n
    $$

    • 当 r > 0时, 表示两个变量正相关,即一个变量值越大则另一个变量也会越大
    • 当 r < 0时, 表示两个变量负相关, 即一个变量值越大则另一个变量值反而越小
    • 当 r = 0时, 表示两个变量不是线性相关
    • 当 r = 1 或 r = -1时, 意味着两个变量X和Y适合用直线方程描述

    image-20200810175311226

    4.计算一列或一组列的汇总统计信息

    使用describe方法,可以计算所有数值类型列的计数、平均值、标准差、最小值和最大值(更精确统计函数使用StatFunctions包)

    image-20200811101129783

    5.行ID

    使用monotonically_increasing_id函数为每行添加一个唯一的ID,它会从0开始,为每行生成一个唯一值。

    image-20200811101952237

    四、处理字符串类型

    1.大小写

    使用initcap函数将会给定字符串中空格分隔的每个单词首字母大写,使用upper或lower将字符串转为大写或小写

    image-20200811103116257

    2.处理字符串周围的空格

    image-20200811104329240

    注:如果lpad或rpad输入数值参数小于字符串长度,它将从字符串右侧删除字符。

    五、正则表达式

    1.regexp_replace替换值

    image-20200811105516132

    2.regexp_extract提取值

    image-20200811113046848

    3.使用translate函数实现字符替换工作

    这是在字符级上完成的操作,并将用给定字符串替换掉所有出现的某字符串。

    image-20200811113722719

    4.使用contains检查是否存在, 返回布尔值

    image-20200811115606100

    使用不定量参数解决问题

    image-20200811120800414

    六、处理日期和时间戳类型

    Spark内部有日历日期的data, 及包括日期和时间信息的timestamp。Spark会尽最大努力正确识别列数据类型。当设置inferSchema为true时,Spark会自动推理出日期与时间戳数据类型。

    注:在2.1版本及之前,如果时区没有被显示指定,Spark会根据计算机时区进行解析。如果有必要的情况下,可以通过设置spark.conf.sessionLocalTimeZone设置会话本地时区,根据java的TimeZone格式设置。

    Spark的TimestampType类只支持二级精度,这意味着如果处理毫秒或微秒,可能需要将数据作为Long型操作才能解决问题。再强制转换为TimeStampType时, 任何更高精度都被删除。

    1.使用current_date current_timestamp获取当前日期和当前时间

    image-20200811161427278

    2.date_add date_sub增减天数

    image-20200811162033213

    3.使用datediff返回两个日期之间的天数, months_between返回两个日期之间的月数

    image-20200811163355127

    4.to_date 使用指定格式将字符串转换为日期数据

    须使用java_simpleDateFrame指定想要的格式。如果Spark无法解析日期,其不会抛出错误,而只是返回null。

    image-20200811170232918

    解决此类问题,需要根据Java SimpleDataFormat标准指定日期格式。

    to_date选择指定一种日期格式, to_timestamp强制要求使用一种日期格式

    image-20200812110426931

    注:面对可能需要处理null值或不同时区及格式的日期时,建议使用显示类型转换,切勿使用隐式类型转换。

    七、空值处理

    在实际应用中,建议始终使用null来表示DF缺少或空的数据。使用null值有利于Spark进行优化。基于DataFrame, 处理null值主要使用.na子包。

    注:对于Spark而言,显式处理空值比隐式处理较好。当声明列没有空值时,这并不是实际意义上的强制无空值,当定义一个数据模式时,其中所有的列被声明为不具有null值类型时,Spark不会强制拒绝空值插入。空值设置本身只是为了帮助Spark SQL处理该列时进行优化。

    1.合并

    使用coalesce函数,实现从一组列中选择第一个非空值,即第一个空值

    image-20200812105806939

    2.ifnull、nullif、nvl、nvl2等SQL函数

    ifnull =》如果第一个值为空,则选择第二个值,并将其默认为第一个。

    nullif =》 如果两个值相等,则返回null, 否则返回第二个值

    nvl =》 若第一个值为null, 则返回第二个值,否则返回第一个值

    nvl2 =》 若第一个值不为null, 返回第二个值, 否则他将返回第一个值

    3.drop

    使用drop删除包含null的行,默认删除包含null值的行。若指定“any”作为参数,当存在一个值为null时,即删除该行;若指定“all”为参数, 只有当所有的值为null或者NaN才能删除该行。也可以通过指定某几列,来对列进行删除空值操作。

    df.na.drop()
    df.na.drop("any")
    df.na.drop("all")
    df.na.drop("all", Seq("StockCode", "InvoiceNo"))
    

    4.fill

    fill函数可以使用一组值填充一列或多列,它可以通过指定一个映射(即一个特定值和一组列)来完成。

    df.na.fill("All Null values become this string")
    
    //需要注意列的类型
    df.na.fill(5, Seq("StockCode", "InvoiceNo"))
    
    //使用映射实现
    val fillColValues = Map("StockCode" -> 5, "Description" -> "No Value")
    df.na.fill(fillColValue)
    

    5.replace

    根据当前值替换掉 某列中所有值,唯一要求时替换值与原始值的类型相同。

    df.na.replace("Description", Map("" -> "UNKNOWN"))
    

    八、复杂类型

    1.结构体

    结构体可以使用“.”访问列或使用getField方法,还可以使用*查询结构体中的所有值。

    image-20200812105559319

    2.数组

    split函数并指定分隔符执行操作

    image-20200812113650578

    求数组长度

    image-20200812145216888

    array_contains 查询数组是否包含某个值

    image-20200812150230416

    explode

    explode函数输入参数为一个包含数组的列,并为该数组的每个值创建一行

    image-20200812160133929

    map

    map映射是通过map函数构建两列内容键值对映射形式。

    image-20200812161441448

    九、JSON类型

    image-20200812172204309

    十、用户自定义函数

    UDF,即用户自定义函数可以使用户使用python或scala编写自己的自定义转换操作,甚至使用外部库。UDF可以将一个或多个列作为输入,同时也可以返回一个或多个列。默认情况下,这些函数被注册为SparkSession或者Context的临时函数。

    image-20200812181017057

  • 相关阅读:
    第五周项目4-静态成员应用
    第五周项目3-用多文件组织多个类的程序
    python的wraps函数
    python函数加括号于不加括号的区别
    socket.error: [Errno 10048]
    tensorflow的MNIST教程
    cidr地址段
    mongodb数据库的存储问题
    搭建巡风扫描器
    mongodb的数据库,集合,数据可介绍。
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13492244.html
Copyright © 2020-2023  润新知