【问题标题】:How to force inferSchema for CSV to consider integers as dates (with "dateFormat" option)?如何强制 CSV 的 inferSchema 将整数视为日期(使用“dateFormat”选项)?
【发布时间】:2018-03-13 18:06:08
【问题描述】:

我使用 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 值,也没有任何格式错误的行。

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

【问题讨论】:

  • 您可以尝试禁用 ("inferSchema", "true") 并提供自定义架构来读取 csv 文件
  • 我可以,但我猜“dateFormat”选项是为了避免按照您的建议进行操作,对吧?
  • 如果我记性还好的话,需要用双引号转义。

标签: apache-spark dataframe apache-spark-sql spark-csv


【解决方案1】:

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

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

因此,我认为问题在于 20171001 在考虑 TimestampType 之前匹配 IntegerType(它使用 timestampFormat 而不是 dateFormat 选项)。

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

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

【讨论】:

    【解决方案2】:

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

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

    具体来说,启用模式推断后,Spark will call tryParseInteger 将正确解析输入和 stop。后续调用将匹配 the second case 并在相同的 tryParseInteger 调用处结束。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    相关资源
    最近更新 更多