将字符串存储为嵌套JSON到JSON文件中的列 - Pyspark。

4
我有一个pyspark数据框,它长下面这样。
+------------------------------------+-------------------+-------------+--------------------------------+---------+
|member_uuid                         |Timestamp          |updated      |member_id                       |easy_id  |
+------------------------------------+-------------------+-------------+--------------------------------+---------+
|027130fe-584d-4d8e-9fb0-b87c984a0c20|2020-02-11 19:15:32|password_hash|ajuypjtnlzmk4na047cgav27jma6_STG|993269700|

我将上述数据框转换为以下形式:
 +---------+---------+-------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+
|attribute|operation|params                                                                                                                                           |timestamp          |
+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+
|profile  |UPDATE   |{"member_uuid":"027130fe-584d-4d8e-9fb0-b87c984a0c20","member_id":"ajuypjtnlzmk4na047cgav27jma6_STG","easy_id":993269700,"field":"password_hash"}|2020-02-11 19:15:32|

使用以下代码:

ll = ['member_uuid', 'member_id', 'easy_id', 'field']
df = df.withColumn('timestamp', col('Timestamp')).withColumn('attribute', lit('profile')).withColumn('operation', lit(col_name)) \
                    .withColumn('field', col('updated')).withColumn('params', F.to_json(struct([x for x in ll])))
    df = df.select('attribute', 'operation', 'params', 'timestamp')

我已将此数据框 df 转换为 JSON 格式,并将其保存到文本文件中。我尝试使用以下代码进行相同的操作:

df_final.toJSON().coalesce(1).saveAsTextFile('file')

该文件包含:
{"attribute":"profile","operation":"UPDATE","params":"{\"member_uuid\":\"027130fe-584d-4d8e-9fb0-b87c984a0c20\",\"member_id\":\"ajuypjtnlzmk4na047cgav27jma6_STG\",\"easy_id\":993269700,\"field\":\"password_hash\"}","timestamp":"2020-02-11T19:15:32.000Z"}

我希望以这种格式保存它,

{"attribute":"profile","operation":"UPDATE","params":{"member_uuid":"027130fe-584d-4d8e-9fb0-b87c984a0c20","member_id":"ajuypjtnlzmk4na047cgav27jma6_STG","easy_id":993269700,"field":"password_hash"},"timestamp":"2020-02-11T19:15:32.000Z"}

to_json将参数列中的值保存为字符串,有没有办法在此保留JSON上下文,以便我可以将其保存为所需的输出?

2个回答

1
不要使用to_json方法来创建数据框中的params列。
技巧在于创建一个struct,并将其写入文件(使用.saveAsTextFile.write.json()),Spark会为结构字段创建JSON。
如果我们已经创建了json对象,并以json格式进行编写,则Spark会添加\以转义Json字符串中已存在的引号示例:
from pyspark.sql.functions import *

#sample data
df=spark.createDataFrame([("027130fe-584d-4d8e-9fb0-b87c984a0c20","2020-02-11 19:15:32","password_hash","ajuypjtnlzmk4na047cgav27jma6_STG","993269700")],["member_uuid","Timestamp","updated","member_id","easy_id"])

df1=df.withColumn("attribute",lit("profile")).withColumn("operation",lit("UPDATE"))

df1.selectExpr("struct(member_uuid,member_id,easy_id) as params","attribute","operation","timestamp").write.format("json").mode("overwrite").save("<path>")

#{"params":{"member_uuid":"027130fe-584d-4d8e-9fb0-b87c984a0c20","member_id":"ajuypjtnlzmk4na047cgav27jma6_STG","easy_id":"993269700"},"attribute":"profile","operation":"UPDATE","timestamp":"2020-02-11 19:15:32"}

df1.selectExpr("struct(member_uuid,member_id,easy_id) as params","attribute","operation","timestamp").toJSON().saveAsTextFile("<path>")

#{"params":{"member_uuid":"027130fe-584d-4d8e-9fb0-b87c984a0c20","member_id":"ajuypjtnlzmk4na047cgav27jma6_STG","easy_id":"993269700"},"attribute":"profile","operation":"UPDATE","timestamp":"2020-02-11 19:15:32"}

0
一个简单的处理方法就是对文件进行替换操作。
sourceData=open('file').read().replace('"{','{').replace('}"','}').replace('\\','')
with open('file','w') as final:
    final.write(sourceData)

这可能不是您正在寻找的,但将实现最终结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接