Spark(31) -- Dataset (DataFrame) 的基础操作补充

    科技2024-01-29  95

    1. 有类型转换

    2. 无类型转换

    3. Column 对象

     Column 表示了 Dataset 中的一个列, 并且可以持有一个表达式, 这个表达式作用于每一条数据, 对每条数据都生成一个值, 之所以有单独这样的一个章节是因为列的操作属于细节, 但是又比较常见, 会在很多算子中配合出现

    4. 缺失值处理

    DataFrame 中什么时候会有无效值 DataFrame 如何处理无效的值 DataFrame 如何处理 null

    缺失值的处理思路  如果想探究如何处理无效值, 首先要知道无效值从哪来, 从而分析可能产生的无效值有哪些类型, 在分别去看如何处理无效值

    什么是缺失值  一个值本身的含义是这个值不存在则称之为缺失值, 也就是说这个值本身代表着缺失, 或者这个值本身无意义, 比如说 null, 比如说空字符串  关于数据的分析其实就是统计分析的概念, 如果这样的话, 当数据集中存在缺失值, 则无法进行统计和分析, 对很多操作都有影响。

    缺失值的类型 常见的缺失值有两种

    null, NaN 等特殊类型的值, 某些语言中 null 可以理解是一个对象, 但是代表没有对象, NaN 是一个数字, 可以代表不是数字 针对这一类的缺失值, Spark 提供了一个名为 DataFrameNaFunctions 特殊类型来操作和处理

    “Null”, “NA”, " " 等解析为字符串的类型, 但是其实并不是常规字符串数据 针对这类字符串, 需要对数据集进行采样, 观察异常数据, 总结经验, 各个击破 DataFrameNaFunctions DataFrameNaFunctions 使用 Dataset 的 na 函数来获取 val df = … val naFunc: DataFrameNaFunctions = df.na 当数据集中出现缺失值的时候, 大致有两种处理方式, 一个是丢弃, 一个是替换为某值, DataFrameNaFunctions 中包含一系列针对空值数据的方案

    DataFrameNaFunctions.drop 可以在当某行中包含 null 或 NaN 的时候丢弃此行

    DataFrameNaFunctions.fill 可以在将 null 和 NaN 充为其它值

    DataFrameNaFunctions.replace 可以把 null 或 NaN 替换为其它值, 但是和 fill 略有一些不同, 这个方法针对值来进行替换

    如何使用 SparkSQL 处理 null 和 NaN ?  首先要将数据读取出来, 此次使用的数据集直接存在 NaN, 在指定 Schema 后, 可直接被转为 Double.NaN

    val schema = StructType( List( StructField("id", IntegerType), StructField("year", IntegerType), StructField("month", IntegerType), StructField("day", IntegerType), StructField("hour", IntegerType), StructField("season", IntegerType), StructField("pm", DoubleType) ) ) val df = spark.read .option("header", value = true) .schema(schema) .csv("dataset/beijingpm_with_nan.csv")

    对于缺失值的处理一般就是丢弃和填充

    丢弃包含 null 和 NaN 的行

    #当某行数据所有值都是 null 或者 NaN 的时候丢弃此行 df.na.drop("all").show() #当某行中特定列所有值都是 null 或者 NaN 的时候丢弃此行 df.na.drop("all", List("pm", "id")).show() #当某行数据任意一个字段为 null 或者 NaN 的时候丢弃此行 df.na.drop().show() df.na.drop("any").show() #当某行中特定列任意一个字段为 null 或者 NaN 的时候丢弃此行 df.na.drop(List("pm", "id")).show() df.na.drop("any", List("pm", "id")).show()

    填充包含 null 和 NaN 的列

    #填充所有包含 null 和 NaN 的列 df.na.fill(0).show() #填充特定包含 null 和 NaN 的列 df.na.fill(0, List("pm")).show() #根据包含 null 和 NaN 的列的不同来填充 import scala.collection.JavaConverters._ df.na.fill(Map[String, Any]("pm" -> 0).asJava).show

    如何使用 SparkSQL 处理异常字符串 ?

    #读取数据集, 这次读取的是最原始的那个 PM 数据集 val df = spark.read .option("header", value = true) .csv("dataset/BeijingPM20100101_20151231.csv") #使用函数直接转换非法的字符串 df.select('No as "id", 'year, 'month, 'day, 'hour, 'season, when('PM_Dongsi === "NA", 0) .otherwise('PM_Dongsi cast DoubleType) .as("pm")) .show() #使用 where 直接过滤 df.select('No as "id", 'year, 'month, 'day, 'hour, 'season, 'PM_Dongsi) .where('PM_Dongsi =!= "NA") .show() #使用 DataFrameNaFunctions 替换, 但是这种方式被替换的值和新值必须同类型 df.select('No as "id", 'year, 'month, 'day, 'hour, 'season, 'PM_Dongsi) .na.replace("PM_Dongsi", Map("NA" -> "NaN")) .show()
    Processed: 0.011, SQL: 8