1.处理 Arrays 的方法
先创建一个包含Array的DataFrame
val df = Seq((Seq("zhangsan","lisi"),23),(Seq("wangwu","zhaoliu"),24)).toDF("name","age")
df.printSchema()
|-- name: array (nullable = true)
| |-- element: string (containsNull = true)
|-- age: integer (nullable = false)
df.show()
+-----------------+---+
| name|age|
+-----------------+---+
| [zhangsan, lisi]| 23|
|[wangwu, zhaoliu]| 24|
+-----------------+---+
对于包含复杂数据类型的 df
,如何取到数组name中的字段数据,有如下几种方法:
df.select(col("name").getItem(0),col("name").getItem(1),col("age")).show()
+--------+-------+---+
| name[0]|name[1]|age|
+--------+-------+---+
|zhangsan| lisi| 23|
|wangwu |zhaoliu| 24|
+--------+-------+---+
//col("name")是字符串
df.select(split(col("name")," ").alias("array_col")).select(expr("array_col[0]")).show(2)
df.select(split(col("name")," ").alias("array_col")).select(col("array_col").getItem(0))
获取数组的长度可以使用 size
方法(也适合于Map)def size(e: Column): Column
, Returns length of array or map.
scala> import org.apache.spark.sql.functions.size import org.apache.spark.sql.functions.size
# 我这里Column是用$方式写的
scala> df.select(split($"name", " ").alias("array_col"))
.withColumn("no_of_array",size($"array_col")).show(2,false)
使用炸裂函数explode
scala> df.withColumn("explode_name",explode($"name")).show()
+-----------------+---+------------+
| name|age|explode_name|
+-----------------+---+------------+
| [zhangsan, lisi]| 23| zhangsan|
| [zhangsan, lisi]| 23| lisi|
|[wangwu, zhaoliu]| 24| wangwu|
|[wangwu, zhaoliu]| 24| zhaoliu|
+-----------------+---+------------+
2.处理 Structs 的方法
先创建一个包含Struct的DataFrame
val df1 = spark.createDataFrame(Seq(("zhangsan",20,15552211521L),("lisi",21,13287994007L),("wangwu",23,15552211523L))).toDF("name","age","phone")
scala> df1.show()
+--------+---+-----------+
| name|age| phone|
+--------+---+-----------+
|zhangsan| 20|15552211521|
| lisi| 21|13287994007|
| wangwu| 23|15552211523|
+--------+---+-----------+
scala> complexdf.printSchema
root
|-- complex: struct (nullable = false)
| |-- name: string (nullable = true)
| |-- age: integer (nullable = false)
|-- phone: long (nullable = false)
scala> val complexdf = df1.selectExpr("struct(name,age) as complex","phone")
scala> complexdf.show()
+--------------+-----------+
| complex| phone|
+--------------+-----------+
|[zhangsan, 20]|15552211521|
| [lisi, 21]|13287994007|
| [wangwu, 23]|15552211523|
+--------------+-----------+
包含复杂数据类型的 complexdf
和之前DataFrame都是一样使用的,区别在于如何取到结构体complex内的字段数据,有如下几种方法:
complexdf.select(col("complex").getField("name")).show()
//getField方法/getItem方法也OK,二者有区别的
+------------+
|complex.name|
+------------+
| zhangsan|
| lisi|
| wangwu|
+------------+
complexdf.select("complex.name").show()
# sql
complexDF.createOrReplaceTempView("complex_df")
spark.sql("select complex.* from complex_df").show(3,false)
spark.sql("select complex.name from complex_df").show(false)
3.处理 Maps 的方法
Map就是key-value对格式的数据,spark sql提供一个 map
方法可以将两个Column转为Map Column, key不能为null ,value可以
4.处理 JSON 的方法
JSON格式的数据是很常见的,Spark也提供了系列方法来解析或者提取JSON对象,但有一点要知道,这种格式的数据是以字符串形式存储的,没有什么JSON类型
get_json_object(e: Column, path: String): Column
,从json字符串中根据给定的json路径提取一个json对象- 是json格式的字符串也可以,
spark.sql("""select get_json_object('{"key1":{"key2":[1,2,3]}}','$.key1.key2')""")
,了解就好
- 是json格式的字符串也可以,
json_tuple(json: Column, fields: String*): Column
,如果json字符串只有一个层级,可以使用该方法提取json对象from_json
,根据给定的Schema将json字符串的Column列解析成对应列to_json
,将多个列转成json字符串的列