混合列中的空字符串在使用 Spark 加载时使行无效

请考虑以下 JSON:


{"col1": "yoyo", "col2": 1.5}

{"col1": "",     "col2": 6}

{"col1": "456",  "col2": ""}

{"col1": 444,    "col2": 12}

{"col1": null,   "col2": 1.7}

{"col1": 3.14,   "col2": null}

我使用(Py)Spark加载,如下所示:


from pyspark.sql import SparkSession

spark = SparkSession.builder.master("local[*]").getOrCreate()

df = spark.read.json("my.json")

df.show()

这将产生:


+----+----+

|col1|col2|

+----+----+

|yoyo| 1.5|

|    | 6.0|

|null|null|  <---===***

| 444|12.0|

|null| 1.7|

|3.14|null|

+----+----+

我很难理解为什么第三行被无效。似乎原因是第二列中唯一的字符串是空字符串,这以某种方式导致空化。请注意,第 2 行也包含一个空字符串,但该行未被清空。""col1


对我来说,这是一个非常令人困惑和意想不到的行为。我无法在文档中找到提示。


这种行为是预期的吗?为什么会这样发生?

我希望第 3 行包含 的字符串和 的空字符串。我怎样才能实现这种行为(这对我来说感觉更自然)?"456"col1""col2


开心每一天1111
浏览 143回答 1
1回答

桃花长相依

使用 Spark 时,无法在单个列中混合使用不同的数据类型。读取 json 文件时,Spark 将尝试推断每列的数据类型(有关更多详细信息,请参阅底部的注释)。在这里,Spark认为是字符串类型并且是双精度的。这可以通过读取 json 文件并在数据帧上使用来确认。这意味着数据是根据这些推断的数据类型进行解析的。因此,Spark将尝试解析为双精度,但显然会失败。(对于它中的第二行,它的工作原理是,因为被推断为字符串类型,因此是有效的输入。col1col2printSchema""col1col1""使用时,可以设置不同的模式。从文档中,我们有:spark.read.jsonmode -允许在解析期间处理损坏记录的模式。如果设置了“无”,则使用缺省值 。PERMISSIVEPERMISSIVE:当它遇到损坏的记录时,将格式错误的字符串放入由 columnNameOfCorruptRecord 配置的字段中,并将其他字段设置为 null。若要保留损坏的记录,用户可以在用户定义的架构中设置名为 columnNameOfCorruptRecorcord 的字符串类型字段。如果架构没有该字段,则会在分析过程中删除损坏的记录。推断架构时,它会在输出架构中隐式添加一个 columnNameOfCorruptRecord 字段。DROPMALFORMED:忽略整个损坏的记录。FAILFAST:在遇到损坏的记录时引发异常。从上面,我们可以看到默认情况下使用模式,如果遇到损坏的记录,则所有字段都设置为 。在这种情况下,就会发生这种情况。要进行确认,可以设置为 ,PERMISSIVEnullmodeFAILFASTspark.read.json("my.json", mode='FAILFAST')这将给出一个例外。这可以通过不推断数据类型并将所有内容读取为字符串来解决。spark.read.json("my.json", primitivesAsString='true')注意:与其他源(如 csv 和 txt)相比,json 的架构推断略有不同,请参阅此处。对于 json 文件,两者都有特殊的处理来处理不区分两者的 json 生成器。对于 csv 文件,具有空字符串的列仍会使整个列被推断为字符串,但对于 json 而言,情况并非如此。""null""作为旁注,替换为例如 in 将使推断的列类型为字符串。"""5"col2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python