【发布时间】:2018-07-17 02:30:21
【问题描述】:
我有一个包含数组的嵌套模式:
root
|-- alarm_time: string (nullable = true)
|-- alarm_id: string (nullable = true)
|-- user: struct (nullable = true)
| |-- name: string (nullable = true)
| |-- family: string (nullable = true)
| |-- address: struct (nullable = true)
| | |-- postalcode: string (nullable = true)
| | |-- line1: string (nullable = true)
| | |-- city: string (nullable = true)
| | |-- country: string (nullable = true)
|-- device: struct (nullable = true)
| |-- device_usage: string (nullable = true)
| |-- device_id: string (nullable = true)
|-- alarm_info: struct (nullable = true)
| |-- type: string (nullable = true)
| |-- reason: string (nullable = true)
| |-- data: struct (nullable = true)
| | |-- alarm_severity: long (nullable = true)
| | |-- extra_info: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- producer: string (nullable = true)
| | | | |-- comment: string (nullable = true)
我过去常常忽略数组字段并使用此代码来扁平化我的架构:
def flattenSchema(schema: StructType, prefix: String = null) : Array[Column] = {
schema.fields.flatMap(f => {
val colName = if (prefix == null) f.name else (prefix + "." + f.name)
f.dataType match {
case st: StructType => flattenSchema(st, colName)
case _ => Array(col(colName))
}
})
}
并像df.select(flattenSchema(df.schema):_*) 一样使用它,但现在我有一个用例也需要保留数组数据,我唯一能想到的就是分解数组并保留多行但我没有运气。由于我将列作为 args 参数传递,因此我无法传递另一个参数。
我怎样才能做到这一点(使用展开数组的扁平化架构)?
【问题讨论】:
-
所以你想在数组列上调用
explode并在同一个select中展平结构?还是我误会了什么? -
@Shaido 是的,你是对的,我想为数组的每个元素单独设置一列
-
您想为每个元素设置单独的列或行吗?使用
explode,您将在自己的行而不是列上获得元素。 -
@Shaido 我想为数组的每个元素获取单独的列(在爆炸数组之后)。我的意思是,如果我有一个包含两个数组的行,它应该为每个数组元素生成 2 行,但每个数组元素应该有单独的列(生产者,评论)
-
我明白了,在这种情况下,你不能先爆炸数组,然后在新的数据帧上使用
flattenSchema吗?在这种情况下,数组已经被分解成多行,每行都包含一个结构(每个都有两个元素,生产者和注释),并且您的方法应该能够展平它。
标签: scala apache-spark apache-spark-sql