Spark 选项:inferSchema vs header = true

Posted

技术标签:

【中文标题】Spark 选项:inferSchema vs header = true【英文标题】:Spark Option: inferSchema vs header = true 【发布时间】:2019-11-17 12:29:46 【问题描述】:

参考pyspark: Difference performance for spark.read.format("csv") vs spark.read.csv

我以为我需要.options("inferSchema" , "true").option("header", "true") 来打印我的标题,但显然我仍然可以打印我的带有标题的csv。

标头和架构有什么区别?我不太明白“inferSchema:自动推断列类型。它需要额外传递一次数据并且默认为false”的含义。

【问题讨论】:

【参考方案1】:

标头和架构是分开的。

标题:

如果 csv 文件有标题(第一行中的列名),则设置 header=true。这将使用 csv 文件中的第一行作为数据框的列名。设置header=false(默认选项)将生成具有默认列名的数据框:_c0_c1_c2 等。

将此设置为 true 或 false 应基于您的输入文件。

架构:

这里引用的架构是列类型。列可以是 String、Double、Long 等类型。使用 inferSchema=false(默认选项)将给出一个数据框,其中所有列都是字符串 (StringType)。根据您要执行的操作,字符串可能不起作用。例如,如果您想添加来自不同列的数字,那么这些列应该是某种数字类型(字符串不起作用)。

通过设置inferSchema=true,Spark 将自动遍历 csv 文件并推断每一列的架构。这需要对文件进行额外的传递,这将导致读取 inferSchema 设置为 true 的文件变慢。但作为回报,数据框很可能在给定其输入的情况下具有正确的架构。


作为使用 inferSchema 读取 csv 的替代方法,您可以在读取时提供架构。这具有比推断架构更快的优势,同时提供具有正确列类型的数据框。此外,对于没有标题行的 csv 文件,可以自动给出列名。要提供架构,请参阅例如:Provide schema while reading csv file as a dataframe

【讨论】:

【参考方案2】:

我们可以通过两种方式在读取 csv 文件时指定架构。

方式1:指定inferSchema=trueheader=true

val myDataFrame = spark.read.options(Map("inferSchema"->"true", "header"->"true")).csv("/path/csv_filename.csv")

注意:在读取数据时使用这种方法,会多创建一个阶段。

方式2:明确指定架构。

val schema = new StructType()
      .add("Id",IntegerType,true)
      .add("Name",StringType,true)
      .add("Age",IntegerType,true)

val myDataFrame = spark.read.option("header", "true")
      .schema(schema)
      .csv("/path/csv_filename.csv")
  

【讨论】:

以上是关于Spark 选项:inferSchema vs header = true的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL inferSchema实现原理探微(Python)

spark csv 包中的 inferSchema

spark-csv 包中的 inferSchema

pyspark如何检查给定的spark数据帧是不是已使用inferSchema = True创建

使用 spark.read.format("com.crealytics.spark.excel") 的 inferSchema 推断日期类型列的双精度

问题排查 | Spark OrcFileFormat inferSchema执行巨慢问题分析