Spark数据帧中的结构体数组解析

2023-12-31

我有一个带有一个结构类型列的数据框。示例数据框架构是:

root
 |-- Data: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- name: string (nullable = true)
 |    |    |-- value: string (nullable = true)

Field name保存列名称和字段value保存列值。中的元素数量Data列未定义,因此可能会有所不同。我需要解析该数据并摆脱嵌套结构。 (大批Explode在这种情况下不起作用,因为一行中的数据属于一个元素)。真正的模式要大得多,并且具有多个数组字段(例如“数据”),因此我的目标是创建一个通用解决方案,我将将该解决方案应用于类似的结构数组。 例子:

样本数据:

val data = Seq(
    """{"Data": [{ "name": "FName", "value": "Alex" }, { "name": "LName",   "value": "Strong"  }]}""",
    """{"Data": [{ "name": "FName", "value": "Robert " }, { "name": "MName",   "value": "Nesta "  }]} { "name": "LName",   "value": "Marley"  }]}"""
)
val df = spark.read.json(spark.sparkContext.parallelize(data))

预期结果:

+-------+------+
|  FName| LName|
+-------+------+
|   Alex|Strong|
|Robert |Marley|
+-------+------+
 

作为解决方案,我创建了一个整体执行的 UDFData柱子。作为输入参数,我传递列名和我想要提取的字段名。

 val find_scheme_name_in_array = udf { (arr: Seq[Row], columnName: String) => {
    var value = ""
    arr.foreach(el =>
        if(el.getAs[String]("name") == columnName){
            value = el.getAs[String]("value")
        }
    )
    value
}}

问题是我正在使用变量value用于存储中间结果,并且我不想为将执行 UDF 的每一行创建一个新的变量。

我执行 UDF 的方式(该查询生成预期结果):

df.select(find_scheme_name_in_array(col("Data"), lit("FName")).as("FName"),find_scheme_name_in_array(col("Data"), lit("LName")).as("LName")).show()

我很高兴听到有关如何改进 UDF 逻辑以及解决解析问题的一些不同方法的任何评论。


我已经通过替换解决了这个问题foreach循环与find method:

val find_scheme_name_in_array = udf { (arr: Seq[Row], columnName: String) =>
    arr.find(_.getAs[String]("name") == columnName) match {
        case Some(i) => i.getAs[String]("value")
        case None => null
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spark数据帧中的结构体数组解析 的相关文章

随机推荐