Spark - 将包含 JSON 字符串的列从 StringType 转换为 Array Type(StringType())

Posted

技术标签:

【中文标题】Spark - 将包含 JSON 字符串的列从 StringType 转换为 Array Type(StringType())【英文标题】:Spark - Convert a coulmn containing JSON string from StringType to ArrayType(StringType()) 【发布时间】:2021-06-07 07:06:24 【问题描述】:

我有一个数据框 df,其中包含如下所示的 json 字符串,

'''["@id":"Party_1","@ObjectID":"Policy_1","@id":"Party_2","@ObjectID":"Policy_2","@id":"Party_3","@ObjectID":"Policy_3"]'''

df 架构:

root
 |-- col1: string (nullable = true)

如何将其转换为字符串数组 (ArrayType(StringType()))?

结果应该是这样的,

['"@id":"Party_1","@OriginatingObjectID":"Policy_1"',
 '"@id":"Party_2","@OriginatingObjectID":"Policy_2"',
 '"@id":"Party_3","@OriginatingObjectID":"Policy_3"']

结果架构:

root
 |-- arr_col: array (nullable = true)
 |          |-- element: string (containsNull = true)

任何帮助将不胜感激。谢谢!

【问题讨论】:

您的“预期结果”没有您描述的架构。您期望的结果是 ArrayType(MapType(StringType()))。请更清楚您的期望。 对不起,我已经更新了结果。预期的结果是 JSON 字符串数组。 【参考方案1】:

您可以使用 from_json 函数获取 json 字段,对值稍作修改,如下所示

data = [
    ('["@id":"Party_1","@ObjectID":"Policy_1","@id":"Party_2","@ObjectID":"Policy_2","@id":"Party_3","@ObjectID":"Policy_3"]', 2767),
    ('["@id":"Party_1","@ObjectID":"Policy_1","@id":"Party_2","@ObjectID":"Policy_2","@id":"Party_3","@ObjectID":"Policy_3"]', 4235)
]

df = spark.createDataFrame(data).toDF(*["value", "count"])\
    .withColumn("value", f.regexp_replace(f.col("value"), "\\[\\", "\"arr\": ["))\
    .withColumn("value", f.regexp_replace(f.col("value"), "\\\\]", "]"))


json_schema = spark.read.json(df.rdd.map(lambda row: row.value)).schema
resultDF = df.select(f.from_json("value", 
schema=json_schema).alias("array_col"))\
    .select("array_col.*")

resultDF.printSchema()
resultDF.show(truncate=False)

如果您想将嵌套的 json 作为字符串,也可以使用自定义架构。

输出架构:

root
 |-- arr: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- @ObjectID: string (nullable = true)
 |    |    |-- @id: string (nullable = true)

输出:

+---------------------------------------------------------------+
|arr                                                            |
+---------------------------------------------------------------+
|[Policy_1, Party_1, Policy_2, Party_2, Policy_3, Party_3]|
|[Policy_1, Party_1, Policy_2, Party_2, Policy_3, Party_3]|
+---------------------------------------------------------------+

【讨论】:

以上是关于Spark - 将包含 JSON 字符串的列从 StringType 转换为 Array Type(StringType())的主要内容,如果未能解决你的问题,请参考以下文章

如何将具有嵌套元素的列从其他列添加到数据框(withColumn)[重复]

PostgreSQL,试图将日期列从 csv 文件复制到表的列

将包含多种字符串日期格式的列转换为 Spark 中的 DateTime

Spark - 使用 JSON 文件的许可模式将所有记录移动到损坏的列

Spark 数据框将嵌套的 JSON 转换为单独的列

将重复的列从 CSV 转换为嵌套的 BigQuery 表?