我的数据集架构看起来像这样
root
|-- col1: string (nullable = false)
|-- col2: string (nullable = false)
|-- col3: timestamp (nullable = false)
|-- col4: map (nullable = false)
| |-- key: string
| |-- value: map (valueContainsNull = true)
| | |-- key: integer
| | |-- value: long (valueContainsNull = true)
col4
是一种地图类型,但在其中,还有另一张地图。
我可以使用explode(col4)
来获取
root
|-- col1: string (nullable = false)
|-- col2: string (nullable = false)
|-- col3: timestamp (nullable = false)
|-- key: string (nullable = false)
|-- value: map (nullable = true)
| |-- key: integer
| |-- value: long (valueContainsNull = true)
我现在应该如何分解value
列?
一种愚蠢的方法是重命名key
列,然后再次展开value
列...但我正在努力做到这一点。
答案 0 :(得分:1)
您需要定义udf
功能以将地图 col4
列展平为
import org.apache.spark.sql.functions._
def flatNestedMap = udf((maps: Map[String,Map[Int, Long]])=> maps.flatMap(x => x._2.map(y => (x._1, y._1, y._2))).toArray)
然后,您可以在explode
函数返回的列上使用一个udf
,然后在select
必要的列中使用
df.withColumn("col4", explode(flatNestedMap(col("col4"))))
.select(col("col1"), col("col2"), col("col3"), col("col4._1").as("outerKey"), col("col4._2").as("innerKey"), col("col4._3").as("innerValue"))
多数民众赞成。我希望答案很有帮助