当前位置: 首页 > 知识库问答 >
问题:

Spark Dataset加载多个CSV文件,文件头位于文件夹中,如果所有文件中的文件头不相同,则报告不匹配

司徒炎彬
2023-03-14

我正在尝试使用spark 2.1.0 API将多个csv文件从hdfs目录加载到spark DataSet中:

val csvData = spark.read.option("header", "true").csv("csvdatatest/")

在“CSVDataTest”文件夹中有多个csv文件。Spark只从第一个文件中提取header,并将其生成为数据集的模式,忽略其余csv文件的header。例如

hadoop fs -ls /user/kumara91/csvdatatest
Found 2 items
/user/kumara91/csvdatatest/controlfile-2017-10-19.csv
/user/kumara91/csvdatatest/controlfile-2017-10-23.csv

hadoop fs -cat /user/kumara91/csvdatatest/controlfile-2017-10-19.csv
Delivery ID,BroadLog ID,Channel,Address,Event type,Event date,File name

hadoop fs -cat /user/kumara91/csvdatatest/controlfile-2017-10-23.csv
Delivery ID,BroadLog ID,Channel,Address,Event type,Event date,File name,dummycolumn

scala> val csvData = spark.read.option("header", "true").csv("csvdatatest/")
csvData: org.apache.spark.sql.DataFrame = [Delivery ID: string, BroadLog ID: string ... 5 more fields]

scala> csvData.schema.fieldNames
res1: Array[String] = Array(Delivery ID, BroadLog ID, Channel, Address, Event type, Event date, File name)

这里,它只从文件“controlfile-2017-10-19.csv”加载了头,并忽略了其他csv文件中带有额外列“dummycolumn”的头。

但是,我想知道是否有任何方法可以使用Spark API而不遍历每个文件,以及为什么Spark从一个文件读取头而忽略其余的文件。

共有1个答案

金飞翼
2023-03-14

如果不以某种方式迭代文件,就无法正确读取数据。在大数据中,基于文件的数据源是基于目录的,而CSV的假设是一个目录中的所有文件都具有相同的模式。对于JSON源代码,不存在与.read.option(“mergeschema”,true)等效的代码。

如果只想检查标题,则需要一次处理一个文件。在获得所有文件的列表后,使用所需的任何方法,最简单的方法是使用如下代码获取文件头:

val paths: Seq[String] = ...
val pathsAndHeaders: Seq[(String, String)] = paths.map { path =>
  val header = sc.textFile(path).take(1).collect.head
  (path, header)
}

如果您有许多CSV,一个更有效的版本是在集群中分发路径,但您必须自己读取文件:

val paths: Seq[String] = ...
val pathsAndHeaders: Seq[(String, String)] = sc.parallelize(paths)
  .map { path =>
    val header = // read first line of file at path
    (path, header)
  }
  .collect

现在已经有了路径和头部,可以做任何需要的事情。例如,一旦将文件分组为具有相同头的组,就可以将一系列路径传递给load()以在一次操作中读取它们。

 类似资料:
  • 我目前正在制作一个Minecraft Mod Loader。 正如您在上面看到的,我有一个名为Client的类。当Minecraft游戏启动时,启动被调用。现在我有一个名为Mods的文件夹,在调用startup时,我需要将Mods从Mods文件夹加载到ArrayList命名模块中。更深入地说,每个Mod将有一个继承这个模块类的主类 因此,在调用startup时,我需要遍历mods文件夹中的每个Mo

  • 我正在从事一个JavaFX8(maven)项目。我想在sources(而不是resources)文件夹中存储一个fxml文件 当我将fxml存储到location/src/main/resources/views/b/MyFxml时。fxml我使用命令加载它时没有错误, 有没有办法从/src/main/java/package/name/RoleView加载我的fxml文件。fxml位置?

  • 我正在处理一个JavaFX8(maven)项目。我想在sources(而不是resources)文件夹中存储fxml文件。 当我将fxml存储到位置/src/main/resources/views/b/myfxml.fxml时, 有没有办法从/src/main/java/package/name/roleview.fxml位置加载我的fxml文件?

  • 问题内容: 我正在尝试仅将原始文件从一个目录复制到另一个目录,但是某些文件具有相同的名称…我正在尝试使用哈希来比较文件,如果其不在目录中发送并且名称相同,它到file_name.something。目前,我正在获取一些文件,并且具有相同名称的文件正在被覆盖…任何人都可以提出建议吗? 问题答案: 您将哈希与文件名进行比较。你需要类似的东西 计算目标文件夹中每个文件的哈希值。 此外,在当前版本中,您的

  • 我有100个不同名称的文件夹,每个文件夹中应该有相同的三个文件,但在某些文件夹中,这三个文件都不存在。 如何删除空文件夹或仅包含一个或两个文件的文件夹? 这是三个文件:

  • 我在同一个文件夹中有数千个csv文件名,如下file_x_x.csv,其中x是1到10000之间的数字。每个文件包括一个标题和一行数据: file_1_1.csv 我的方法: 我不知道如何在最后创建一个唯一的文件。你能看一下上面的代码并告诉我如何获得所需的输出吗?如果我错过了什么?