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的操作。
在数据处理中经常会用到
希望她会越来越好。