【问题标题】:PySpark, importing schema through JSON filePySpark,通过 JSON 文件导入模式
【发布时间】:2015-11-08 18:39:28
【问题描述】:

tbschema.json 看起来像这样:

[{"TICKET":"integer","TRANFERRED":"string","ACCOUNT":"STRING"}]

我使用以下代码加载它

>>> df2 = sqlContext.jsonFile("tbschema.json")
>>> f2.schema
StructType(List(StructField(ACCOUNT,StringType,true),
    StructField(TICKET,StringType,true),StructField(TRANFERRED,StringType,true)))
>>> df2.printSchema()
root
 |-- ACCOUNT: string (nullable = true)
 |-- TICKET: string (nullable = true)
 |-- TRANFERRED: string (nullable = true)
  1. 当我希望元素按照它们在 JSON 中出现的顺序时,为什么要对架构元素进行排序。

  2. 数据类型integer在导出JSON后转换为StringType,如何保留数据类型。

【问题讨论】:

    标签: python json apache-spark pyspark apache-spark-sql


    【解决方案1】:

    当我希望元素按照它们在 json 中出现的顺序时,为什么要对架构元素进行排序。

    因为不能保证字段的顺序。虽然没有明确说明,但当您查看 JSON 阅读器文档字符串中提供的示例时,它会变得很明显。如果您需要特定的顺序,您可以手动提供架构:

    from pyspark.sql.types import StructType, StructField, StringType
    
    schema = StructType([
        StructField("TICKET", StringType(), True),
        StructField("TRANFERRED", StringType(), True),
        StructField("ACCOUNT", StringType(), True),
    ])
    df2 = sqlContext.read.json("tbschema.json", schema)
    df2.printSchema()
    
    root
     |-- TICKET: string (nullable = true)
     |-- TRANFERRED: string (nullable = true)
     |-- ACCOUNT: string (nullable = true)
    

    json导出后数据类型integer转成StringType了,如何保留数据类型。

    JSON 字段 TICKET 的数据类型是字符串,因此 JSON 读取器返回字符串。它是 JSON 阅读器,而不是某种模式阅读器。

    一般来说,您应该考虑一些适当的格式,这些格式支持开箱即用,例如ParquetAvroProtocol Buffers。但如果你真的想玩 JSON,你可以像这样定义穷人的“模式”解析器:

    from collections import OrderedDict 
    import json
    
    with open("./tbschema.json") as fr:
        ds = fr.read()
    
    items = (json
      .JSONDecoder(object_pairs_hook=OrderedDict)
      .decode(ds)[0].items())
    
    mapping = {"string": StringType, "integer": IntegerType, ...}
    
    schema = StructType([
        StructField(k, mapping.get(v.lower())(), True) for (k, v) in items])
    

    JSON 的问题在于,对于字段排序确实没有任何保证,更不用说处理丢失的字段、不一致的类型等等。因此,使用上述解决方案实际上取决于您对数据的信任程度。

    您也可以使用built-in schema import / export utilities

    【讨论】:

    • 有趣的解决方案,IntergerType() 之后的 () 被移至 Struct 的创建,而不是在您的地图中的任何特殊原因?这样您就可以进行DecimalType(x,y) .. 谢谢,真的很有帮助!
    猜你喜欢
    • 2017-11-19
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 2020-05-04
    • 2017-08-16
    • 1970-01-01
    • 2016-08-03
    相关资源
    最近更新 更多