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

问题描述 投票:0回答:1

考虑以下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|
+----+----+

我很难理解为什么第三行无效。似乎原因是第二列中唯一的字符串是空字符串"",这某种程度上导致了无效化。请注意,col1在第二行中也包含一个空字符串,但该行not无效。

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

  • 这是预期的行为吗?为什么会这样发生?
  • 我希望第三行为"456"保留字符串col1,为""保留空字符串col2。我该如何实现这种行为(对我来说,这自然得多)?
python apache-spark pyspark inference
1个回答
0
投票

使用Spark时无法在不同的列中混合使用不同的数据类型

读取json文件时,Spark会尝试推断每列的数据类型。在这里,Spark认为col1是字符串类型,col2是双精度类型。可以通过读取json文件并在数据帧上使用printSchema来确认。这意味着将根据这些推断的数据类型来解析数据。因此,Spark将尝试将""解析为一个显然失败的double。

使用spark.read.json时,可以设置不同的模式。在documentation中,我们有:

模式

-允许一种在解析期间处理损坏记录的模式。如果没有设置,它使用默认值PERMISSIVE
  • PERMISSIVE:遇到损坏的记录时,将格式错误的字符串放入由columnNameOfCorruptRecord配置的字段中,并将其他字段设置为null。为了保留损坏的记录,用户可以在用户定义的模式中设置一个名为columnNameOfCorruptRecord的字符串类型字段。如果架构没有该字段,它将在解析期间删除损坏的记录。推断架构时,它会在输出架构中隐式添加columnNameOfCorruptRecord字段。
  • DROPMALFORMED:忽略整个损坏的记录。
  • FAILFAST:遇到损坏的记录时引发异常。

从上面,我们可以看到默认情况下使用PERMISSIVE模式,并且如果遇到损坏的记录,则所有字段都将设置为null。这就是这种情况。要确认,可以将mode设置为FAILFAST

spark.read.option('mode','FAILFAST').json("my.json")

这将带来例外。

© www.soinside.com 2019 - 2024. All rights reserved.