为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

开心每一天1111 2022-09-06 16:36:58
请考虑以下 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 SparkSessionspark = 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
查看完整描述

1 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

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


读取 json 文件时,Spark 将尝试推断每列的数据类型(有关更多详细信息,请参阅底部的注释)。在这里,Spark认为是字符串类型并且是双精度的。这可以通过读取 json 文件并在数据帧上使用来确认。

这意味着数据是根据这些推断的数据类型进行解析的。因此,Spark将尝试解析为双精度,但显然会失败。(对于它中的第二行,它的工作原理是,因为被推断为字符串类型,因此是有效的输入。col1col2printSchema""col1col1""


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


mode -

允许在解析期间处理损坏记录的模式。如果设置了“无”,则使用缺省值 。PERMISSIVE


PERMISSIVE:当它遇到损坏的记录时,将格式错误的字符串放入由 columnNameOfCorruptRecord 配置的字段中,并将其他字段设置为 null。若要保留损坏的记录,用户可以在用户定义的架构中设置名为 columnNameOfCorruptRecorcord 的字符串类型字段。如果架构没有该字段,则会在分析过程中删除损坏的记录。推断架构时,它会在输出架构中隐式添加一个 columnNameOfCorruptRecord 字段。

DROPMALFORMED:忽略整个损坏的记录。

FAILFAST:在遇到损坏的记录时引发异常。

从上面,我们可以看到默认情况下使用模式,如果遇到损坏的记录,则所有字段都设置为 。在这种情况下,就会发生这种情况。要进行确认,可以设置为 ,PERMISSIVEnullmodeFAILFAST


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

这将给出一个例外。


这可以通过不推断数据类型并将所有内容读取为字符串来解决。


spark.read.json("my.json", primitivesAsString='true')

注意:与其他源(如 csv 和 txt)相比,json 的架构推断略有不同,请参阅此处。对于 json 文件,两者都有特殊的处理来处理不区分两者的 json 生成器。对于 csv 文件,具有空字符串的列仍会使整个列被推断为字符串,但对于 json 而言,情况并非如此。""null""


作为旁注,替换为例如 in 将使推断的列类型为字符串。"""5"col2


查看完整回答
反对 回复 2022-09-06
  • 1 回答
  • 0 关注
  • 142 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号