Arrays 正在分析JSON字符串Pyspark dataframe列,该列在其中一列中具有数组字符串
我试图读取一个JSON文件,并将“jsonString”和包含数组的底层字段解析为pyspark数据帧 下面是json文件的内容Arrays 正在分析JSON字符串Pyspark dataframe列,该列在其中一列中具有数组字符串,arrays,json,pyspark,Arrays,Json,Pyspark,我试图读取一个JSON文件,并将“jsonString”和包含数组的底层字段解析为pyspark数据帧 下面是json文件的内容 [{"jsonString": "{\"uid\":\"value1\",\"adUsername\":\"value3\",\"courseCertifications\":[{\"uid\":\"value2\",\"courseType\":\"TRAINING\"},{\"uid\":\"TEST\",\"courseType\":\"TRAINING\"}]
[{"jsonString": "{\"uid\":\"value1\",\"adUsername\":\"value3\",\"courseCertifications\":[{\"uid\":\"value2\",\"courseType\":\"TRAINING\"},{\"uid\":\"TEST\",\"courseType\":\"TRAINING\"}],\"modifiedBy\":\"value4\"}","transactionId": "value5", "tableName": "X"},
{"jsonString": "{\"uid\":\"value11\",\"adUsername\":\"value13\",\"modifiedBy\":\"value14\"}","transactionId": "value15", "tableName": "X1"},
{"jsonString": "{\"uid\":\"value21\",\"adUsername\":\"value23\",\"modifiedBy\":\"value24\"}","transactionId": "value25", "tableName": "X2"}]
我能够解析字符串“jsonString”的内容,并使用下面的逻辑选择所需的列
df = spark.read.json('path.json',multiLine=True)
df = df.withColumn('courseCertifications', explode(array(get_json_object(df['jsonString'],'$.courseCertifications'))))
现在我的最终目标是从“courseCertifications”解析字段“courseType”,并为每个实例创建一行
我使用下面的逻辑来获取“courseType”
我能够获得“courseType”的内容,但作为一个字符串,如下所示
[Row(new=u'["TRAINING","TRAINING"]')]
我的最终目标是创建一个包含列transactionId、jsonString.uid、jsonString.adUsername、jsonString.courseCertifications.uid、jsonString.courseCertifications.courseType的数据框架
df = df.withColumn('new',get_json_object(df.courseCertifications, '$[*].courseType'))
- 我需要保留所有行并为courseCertifications.uid/courseCertifications.courseType的每个数组实例创建多行
- 解决问题的一种优雅方式是创建json字符串的模式,然后使用
from_json
函数解析它
导入pyspark.sql.f函数
从pyspark.shell导入spark
从pyspark.sql.types导入ArrayType、StringType、StructType和StructField
df=spark.read.json('your_path',multiLine=True)
schema=StructType([
StructField('uid',StringType()),
StructField('adUsername',StringType()),
StructField('modifiedBy',StringType()),
StructField('courseCertifications',ArrayType(
结构类型([
StructField('uid',StringType()),
StructField('courseType',StringType())
])
))
])
df=df\
.withColumn('tmp',f.from_json(df.jsonString,schema))\
.withColumn('adUsername',f.col('tmp')。adUsername)\
.withColumn('uid',f.col('tmp').uid)\
.withColumn('modifiedBy',f.col('tmp')。modifiedBy)\
.带列('tmp',f.explode(f.col('tmp')。课程证书))\
.withColumn('course_uid',f.col('tmp').uid)\
.withColumn('course_type',f.col('tmp')。courseType)\
.drop('jsonString','tmp')
df.show()
输出:
+-------------+------+----------+----------+----------+-----------+
|transactionId|uid |adUsername|modifiedBy|course_uid|course_type|
+-------------+------+----------+----------+----------+-----------+
|value5 |value1|value3 |value4 |value2 |TRAINING |
|value5 |value1|value3 |value4 |TEST |TRAINING |
+-------------+------+----------+----------+----------+-----------+
谢谢@Kafels!这是可行的,而不是定制的模式,我正在做下面的工作来获取“jsonString”的结构,因为它可能包含不同的列,具体取决于JSON文件
json_schema=spark.read.json(df.rdd.map(lambda row:row.jsonString)).schema
df=df.withColumn('jsonString',from_json(df['jsonString',json_schema))
请分享您的想法。您的建议代码非常好,因为不需要映射模式总是从json文件中有一个新的或删除的列谢谢@Kafels,我注意到只有字段“courseCertifications”的记录被保留,而所有其他记录都被删除。我的要求是,如果任何一行都不存在“courseCertifications”字段,则获取所有记录并填充NULL。编辑问题中的JSON,并使用更多值向debugupdated问题添加更多值,还添加了关于o/p数据框的更多信息。