8

我使用 Spark 2.2.0

我正在读取一个 csv 文件,如下所示:

val dataFrame = spark.read.option("inferSchema", "true")
                          .option("header", true)
                          .option("dateFormat", "yyyyMMdd")
                          .csv(pathToCSVFile)

此文件中有一个日期列,并且所有记录的值都等于20171001该特定列的值。

问题是 spark 推断该列的类型是integer而不是date. 当我删除该"inferSchema"选项时,该列的类型是string.

此文件中没有null值,也没有任何格式错误的行。

这个问题的原因/解决方案是什么?

4

2 回答 2

9

如果我的理解是正确的,那么代码暗示了以下类型推断的顺序(首先检查第一个类型):

  • NullType
  • IntegerType
  • LongType
  • DecimalType
  • DoubleType
  • TimestampType
  • BooleanType
  • StringType

有了这个,我认为问题是在考虑之前20171001匹配(使用不选项)。IntegerTypeTimestampTypetimestampFormatdateFormat

一种解决方案是定义模式并将其与schema运算符 (of DataFrameReader) 一起使用,或者让 Spark SQL 推断模式并使用cast运算符。

如果字段数量不高,我会选择前者。

于 2017-10-02T16:54:56.733 回答
4

在这种情况下,由于格式不明确,您根本不能依赖模式推断。

由于输入可以被解析为IntegerType(或任何更高精度的数字格式)以及TimestamType前者具有更高的优先级(内部 Spark 尝试IntegerType-> LongType-> DecimaType-> DoubleType-> TimestampType)推理机制永远不会达到TimestampType大小写。

具体来说,启用模式推断后,Spark将调用tryParseInteger,它将正确解析输入并停止。随后的调用将匹配第二种情况并在同一个tryParseInteger调用中结束。

于 2017-10-02T16:52:58.043 回答