曾经为此苦苦挣扎了一段时间,但仍然无法确定。
我正在尝试flatMap(或将x
与.withColumn
一起使用,因为它似乎更容易,因此我不会丢失列名),但是我总是遇到错误{{1} }。
我已经重新审视了一些类似的问题,但是由于它们的架构太简单,它们都没有引人注意。
我正在尝试使用flatMap的架构列如下...
explode()
我想要通过这样调用explode()来实现的目标...
UDTF expected 2 aliases but got 'name' instead
...是为了获得没有嵌套Map和Struct的行,所以我得到的行数与变体相同。
示例输入
StructField(CarMake,
StructType(
List(
StructField(
Models,
MapType(
StringType,
StructType(
List(
StructField(Variant, StringType),
StructField(GasOrPetrol, StringType)
)
)
)
)
)
))
示例输出
carsDS
.withColumn("modelsAndVariant", explode($"carmake.models"))
基本上将嵌套地图及其内部Strutt都保留在同一级别。
答案 0 :(得分:1)
尝试一下:
case class Models(variant:String, gasOrPetrol:String)
case class CarMake(brand:String, models : Map[String, Models] )
case class MyRow(carMake:CarMake)
val df = List(
MyRow(CarMake("volvo",Map(
"850" -> Models("T5","petrol"),
"V50" -> Models("T5","petrol")
)))
).toDF()
df.printSchema()
df.show()
给予
root
|-- carMake: struct (nullable = true)
| |-- brand: string (nullable = true)
| |-- models: map (nullable = true)
| | |-- key: string
| | |-- value: struct (valueContainsNull = true)
| | | |-- variant: string (nullable = true)
| | | |-- gasOrPetrol: string (nullable = true)
+--------------------+
| carMake|
+--------------------+
|[volvo, [850 -> [...|
+--------------------+
现在爆炸,请注意withColumn
不起作用,因为地图上的èxplode
返回2列(key
和value
),因此您需要使用{{1 }}:
select
给予:
val cols: Array[Column] = df.columns.map(col)
df
.select((cols:+explode($"carMake.models")):_*)
.select((cols:+$"key".as("model"):+$"value.*"):_*)
.show()