Spark SQL中的条件筛选以及case when表达

baby 你就是我的唯一

Filter过滤

        filter和where都可以进行过滤,可以根据指定的一个或多个条件或者SQL表达式来过滤掉DatFrame的行。

        在学习过滤之前,先来讲一个问题,在生产数据当中,可能会有很多的空数据,也就是Null,那么如果去掉null值。在Spark中,如果使用column === null 这样是会报错的。最好的方式使用is null和is not null。

        先来过滤一下

val data = Seq( ("James",null,"M"), ("Anna","NY","F"), ("Julia",null,null) )

 import spark.implicits._ 
val columns = Seq("name","state","gender") 
val df = data.toDF(columns:_*) df.show()

过滤掉null值

        df.filter(df("state").isNotNull).show()

        过滤出来state不为空的值,最终的结果只有第二条,Anna

        创建DataFrame

val arrayStructureData = Seq(
 Row(Row("James", "", "Smith"), List("Java", "Scala", "C++"), "OH", "M"), 
Row(Row("Anna", "Rose", ""), List("Spark", "Java", "C++"), "NY", "F"),
 Row(Row("Julia", "", "Williams"), List("CSharp", "VB"), "OH", "F"), 
Row(Row("Maria", "Anne", "Jones"), List("CSharp", "VB"), "NY", "M"),
 Row(Row("Jen", "Mary", "Brown"), List("CSharp", "VB"), "NY", "M"), 
Row(Row("Mike", "Mary", "Williams"), List("Python", "VB"), "OH", "M") )

 //字段名 
val schema = new StructType()
 .add("name", new StructType() 
.add("firstname", StringType) 
.add("middlename", StringType) 
.add("lastname", StringType)) 
.add("languages",ArrayType(StringType))
 .add("state", StringType) 
.add("gender", StringType) 
//创建dataFrame 
val dataFrame = sparkSession.createDataFrame(
sparkSession.sparkContext.parallelize(arrayStructureData), schema)
dataFrame.printSchema()

        name字段为Struct,嵌套字段,里面包含firsstname,middlename,lastname

        languages字段为Array字段,里面含有数组

        DataFrame filter()with Column条件

        过滤出来state为OH的字段 

  dataFrame.filter(dataFrame("state") ==== "OH").show()

        如果是使用带有条件的Column从DataFrame过滤行,需要用 "==="来进行比较,如果是使用SQl表达式,那么就使用"=="。

带有SQL表达式的DataFrame filter

        dataFrame.filter("gender == 'M'").show()

        上面语句的意思就是过滤出来性别为女性的人。

        使用SQL表达式的时候,不再是使用"==="来进行比较。

多条件过滤

        对于filter可以使用&& || ! 的基于多个条件的 Spark DataFrame上面运行。可以使用带有条件的Column也可以使用SQL 表达式进行过滤

   dafaFrame.filter(col("state") === "OH" && col("gender) === "M").show()

        过滤出来state为OH并且性别为女性的信息

 

对数组列进行过滤

        对数组中的column进行过滤的时候,可以使用Spark SQL的相关函数array_contains(),该函数检查一个值是否被包含在数组中,如果存在则为true,否则返回false。

        也就是说这个filter里面的参数是Boolean类型的

    dataFrame.filter(array_contains(col("languages"),"Java")).show()

        对于language数组字段,如果该数组字段里面包含Java则打印出来。

过滤嵌套结构列

        如果dataFrame包含嵌套的Struct columns,可以使用嵌套字段.字段名。

        dataFrame.filter(col("name.firstname") === "Williams").show()

        显而易见的是,使用where用的最多还是SQL表达式,如果使用filter的话可以有多种选择,既可以使用带有列的filter也可以使用Sql 表达式

 

Spark SQL条件语句

        在平常的SQL当中,最常用的不是if,而是case when。但是在平常的编程当中,用的最多还是if else。当然啦,在Spark SQL里面也存在case when。

        在上面的图中,gender(性别)这个列中,里面有空值,对于空值我们不能置之不理,可以对空值打一个标记。

        如果是空值,显示出来"UnKnown",如果是"M"则显示“Male”,如果是“F”则显示"Female"

dataFrame.withColumn("new_gender",when(dataFrame("gender") ==="M","Male") .when(dataFrame("gender") === "F","Female") 
.otherwise("Unknown")

在Spark SQL中case when

        与SQL的语法类似,case when then else 。

dataframe.withColumn("new_gender",
expr(" case when gender = 'M' then 'male' 
when gender = 'F' then 'Female' 
else 'Unknown' end"))

 

使用&&和||操作

val dataFrame3 = Seq((6, "a", "4"), 
(67, "a", "0"),
 (70, "b", "4"), 
(71, "b", "4")).toDF("id", "code", "amt") 
dataFrame3.withColumn("new_column", 
when(dataFrame3("code") === "a" || dataFrame3("code") ==="d","A") 
.when(dataFrame3("code") === "b" && dataFrame3("amt") === "4","B") 
.otherwise("A1")).show()

 

总结

        本篇博客讲解的是对于空值的处理以及类似于SQL的case when和if else的操作。

        在数据处理中经常会用到

        希望她会越来越好。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值