Spark之处理复杂数据类型(Struct、Array、Map、JSON字符串等)

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_tuple(json: Column, fields: String*): Column ,如果json字符串只有一个层级,可以使用该方法提取json对象
  • from_json ,根据给定的Schema将json字符串的Column列解析成对应列
  • to_json ,将多个列转成json字符串的列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据翻身

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值