Python 从PySpark数据帧(结构化流数据)中的嵌套结构中分解任意数量的JSON字段

Python 从PySpark数据帧(结构化流数据)中的嵌套结构中分解任意数量的JSON字段,python,pyspark,databricks,Python,Pyspark,Databricks,我正在通过物联网和API设备处理Databricks结构化流媒体环境中的一些流媒体数据 我的模式如下: root |-- body: string (nullable = true) |-- partition: string (nullable = true) |-- offset: string (nullable = true) |-- idNumber: long (nullable = true) |-- publishTime: timestamp (nullabl

我正在通过物联网和API设备处理Databricks结构化流媒体环境中的一些流媒体数据

我的模式如下:

    root
 |-- body: string (nullable = true)
 |-- partition: string (nullable = true)
 |-- offset: string (nullable = true)
 |-- idNumber: long (nullable = true)
 |-- publishTime: timestamp (nullable = true)
 |-- make: string (nullable = true)
 |-- partitionKey: string (nullable = true)
 |-- properties: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)
 |-- properties_sys: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)
 |-- date: date (nullable = true)
my body列包含嵌套的json,可以是一层或两层的深度

i、 e

我有一些函数可以帮助我导出进入DataRicks环境的每个唯一流的结构类型,但这是基于静态列表的,我需要在提交配置文件之前定义静态列表

如果我们想象这个物联网设备在运行我的功能后测量天气,我会得到(这是
主体
列的结构)

现在,要分解嵌套列,我只需手动使用以下代码行:

parsed_df = df.withColumn("body", from_json("body", schema)).select(col('partition'), 
col('offset'), col('idNumber'),col('publishTime'),col('make'),col('partitionKey'),
col('properties'),col('properties_sys'),col('date'),col('body.*'))
这完全不需要测试我的json,但由于我的IoT设备与一些API数据混合,我可能会在
body
列中得到一个新字段,该字段没有
StructType
,因此我无法手动定义模式


所以我的问题是,有没有一种方法可以定义动态
explode
,或者任何人都使用过一种方法来创建一个动态模式,我可以事先存储/使用它?

spark 2.4+有一个json的函数
schema\u,如果您不在行级别执行此操作,它可能会有所帮助@jxc看起来很有前途,您有使用它的经验吗?您可以从批处理的第一行获取一个JSON行示例:
sample\u JSON=df.select('body').first().body
,然后schema=spark.range(1).select(schema\u of_JSON(sample\u JSON).别名('schema')).first().schema获取DDL格式的模式,然后可以在from_json()函数中使用该模式。我以前的一篇文章:。如果任何StructType列/字段的字段名中有点、空格等,您可能希望在架构字符串上使用
re.sub
将字段名用回号括起来。@jxc awesome,为什么不添加答案?这与我自己的自定义解决方案非常接近,我实际上将50行导出到Pandas中,以展平JSON,然后基于COL创建一个模式以进行分解。spark 2.4+有一个函数
schema\u of_JSON
,如果不在行级别执行此操作,它可能会有所帮助@jxc看起来很有前途,您有使用它的经验吗?您可以从批处理的第一行获取一个JSON行示例:
sample\u JSON=df.select('body').first().body
,然后schema=spark.range(1).select(schema\u of_JSON(sample\u JSON).别名('schema')).first().schema获取DDL格式的模式,然后可以在from_json()函数中使用该模式。我以前的一篇文章:。如果任何StructType列/字段的字段名中有点、空格等,您可能希望在架构字符串上使用
re.sub
将字段名用回号括起来。@jxc awesome,为什么不添加答案?这与我自己的定制解决方案非常接近,我实际上将50行导出到Pandas中,以展平JSON,然后基于COL创建一个模式进行分解。
data = {'id' : 1,
         'temp' : 28}
 schema = [StructField(humidity,FloatType,true),
 StructField(rainfall,LongType,true),
 StructField(timestamp,DateType,true),
 StructField(city,StringType,true)]
parsed_df = df.withColumn("body", from_json("body", schema)).select(col('partition'), 
col('offset'), col('idNumber'),col('publishTime'),col('make'),col('partitionKey'),
col('properties'),col('properties_sys'),col('date'),col('body.*'))