Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从PySpark数据帧创建嵌套JSON_Json_Dataframe_Apache Spark_Pyspark_Nested - Fatal编程技术网

从PySpark数据帧创建嵌套JSON

从PySpark数据帧创建嵌套JSON,json,dataframe,apache-spark,pyspark,nested,Json,Dataframe,Apache Spark,Pyspark,Nested,此平面json转换为pyspark中的嵌套json { 'event_type': 'click', 'id': '223', 'person_id': 201031940, 'category': 'Chronicles', 'approved_content': 1 } 到 以下是您可以做的: 定义一个模式,并使用模式将平面json转换为数据帧。 注册两个UDF以构建用户和事件映射。 在数据帧中使用UDFs寄存器添加新列user和event(用

此平面json转换为pyspark中的嵌套json

{
    'event_type': 'click', 
    'id': '223',
    'person_id': 201031940, 
    'category': 'Chronicles', 
    'approved_content': 1
}


以下是您可以做的:

定义一个模式,并使用模式将平面json转换为数据帧。 注册两个UDF以构建用户和事件映射。 在数据帧中使用UDFs寄存器添加新列user和event(用户和事件) 删除多余的列 以下是完整的代码:

from pyspark.sql.types import (
    StringType,
    StructField,
    StructType,
    MapType
)
from pyspark.sql.functions import udf

events_schema = StructType([
    StructField('event_type', StringType(), True),
    StructField('id', StringType(), True),
    StructField('person_id', StringType(), True),
    StructField('category', StringType(), True),
    StructField('approved_content', StringType(), True),
])

events = [{
    'event_type': 'click',
    'id': '223',
    'person_id': 201031940,
    'category': 'Chronicles',
    'approved_content': 1
}]
df = spark.createDataFrame(events, schema=events_schema)

build_user_udf = udf(lambda id, person_id: {
    'id': id,
    'person_id': person_id
}, MapType(StringType(), StringType()))

build_event_udf = udf(lambda category, approved_content: {
    'category': category,
    'approved_content': approved_content
}, MapType(StringType(), StringType()))

nested_event_df = (
    df
    .withColumn('user', build_user_udf(df['id'], df['person_id']))
    .withColumn('event', build_event_udf(df['category'], df['approved_content']))
    .drop('id')
    .drop('person_id')
    .drop('category')
    .drop('approved_content')
)
嵌套的_事件_df.toJSON.first

“{事件类型:单击,用户:{id:223,人员id:201031940},事件:{批准的内容:1,类别:历史记录}”

嵌套的\u事件\u df.take1

[Rowevent_type='click',user={'id':'223','person_id':'201031940'},event={'approved_content':'1','category':'Chronicles'}]


这是一个非常基本的版本,但如果您愿意,您可以进行更多优化。

您也可以不使用UDF来进行优化,因为UDF效率更高,如果您处理大量记录,则会产生显著的影响:

import pyspark.sql.fuctions as f
events_schema = StructType([
    StructField('event_type', StringType(), True),
    StructField('id', StringType(), True),
    StructField('person_id', StringType(), True),
    StructField('category', StringType(), True),
    StructField('approved_content', StringType(), True),
])

events = [{
    'event_type': 'click',
    'id': '223',
    'person_id': 201031940,
    'category': 'Chronicles',
    'approved_content': 1
}]
df = spark.createDataFrame(events, schema=events_schema)
newDf = (df
          .withColumn('user', f.struct(df.id, df.person_id))
          .withColumn('event', f.struct(df.category, df.approved_content))
          .withColumn('nestedEvent', f.struct(f.col('user'), f.col('event')))
          .select('nestedEvent'))

添加用户密钥。添加事件键。在事件类型之后调用每个值。删除那些键值对。将调用的键值对插入到添加的键中。太好了,这就是我要找的。次要的是,我可以让嵌套列中的字段在各自的引号中,而不是在值中吗?我们需要在注册UDF时应用类型-我做了必要的更改并更新了代码段。
import pyspark.sql.fuctions as f
events_schema = StructType([
    StructField('event_type', StringType(), True),
    StructField('id', StringType(), True),
    StructField('person_id', StringType(), True),
    StructField('category', StringType(), True),
    StructField('approved_content', StringType(), True),
])

events = [{
    'event_type': 'click',
    'id': '223',
    'person_id': 201031940,
    'category': 'Chronicles',
    'approved_content': 1
}]
df = spark.createDataFrame(events, schema=events_schema)
newDf = (df
          .withColumn('user', f.struct(df.id, df.person_id))
          .withColumn('event', f.struct(df.category, df.approved_content))
          .withColumn('nestedEvent', f.struct(f.col('user'), f.col('event')))
          .select('nestedEvent'))