PySpark中如何将JSON Schema的数组类型转换为字符串类型?
解决方案
针对PySpark解析JSON后字段为数组类型的问题,根据数据场景不同,有两种直接的解决方式:
方法1:用explode展开数组(适用于data数组含多个元素的场景)
如果原始JSON的data数组可能包含多个对象,需要将每个对象拆分为单独行,使用explode函数展开数组即可:
from pyspark.sql import Row from pyspark.sql.types import StructType, StructField, ArrayType, IntegerType, StringType from pyspark.sql.functions import from_json, col, explode jsonData = '{"data" : [{"number":1,"word": "One"}]}' df = spark.createDataFrame([Row(values=jsonData)]) schema = StructType([ StructField("data", ArrayType(StructType([ StructField('number', IntegerType()), StructField('word', StringType()) ]))) ]) df.withColumn('datavals', from_json(col('values'), schema)) \ .select(explode(col('datavals.data')).alias('data_item')) \ .select('data_item.number', 'data_item.word') \ .show(truncate=False)
输出结果:
+------+-----+ |number|word | +------+-----+ |1 |One | +------+-----+
方法2:直接提取数组首个元素(适用于data数组仅含单个元素的场景)
如果确定data数组永远只有一个对象,可直接通过索引[0]提取数组中的唯一元素:
from pyspark.sql import Row from pyspark.sql.types import StructType, StructField, ArrayType, IntegerType, StringType from pyspark.sql.functions import from_json, col jsonData = '{"data" : [{"number":1,"word": "One"}]}' df = spark.createDataFrame([Row(values=jsonData)]) schema = StructType([ StructField("data", ArrayType(StructType([ StructField('number', IntegerType()), StructField('word', StringType()) ]))) ]) df.withColumn('datavals', from_json(col('values'), schema)) \ .selectExpr("datavals.data[0].number as number", "datavals.data[0].word as word") \ .show(truncate=False)
输出结果:
+------+-----+ |number|word | +------+-----+ |1 |One | +------+-----+
问题原因说明
原代码中datavals.data是数组类型字段,直接取datavals.data.number会把数组内每个元素的number值收集为新数组,因此输出为[1]和[One]。通过上述两种方式,要么拆分数组生成多行,要么直接提取唯一元素,即可得到单个值类型的字段。
内容的提问来源于stack exchange,提问作者Madhav Jadhav
相关产品推荐
相关产品推荐

