有没有办法使用名称不同于 part* 的 scala 在 spark 3.0.1 中导出 csv 或其他文件?

Is there a way to export csv or other files in spark 3.0.1 using scala with name different than part*?

我使用 scala 在 spark 中创建了一个二维立方体。数据来自两个不同的数据框。名称是“borrowersTable”和“loansTable”。它们是使用“createOrReplaceTempView”选项创建的,因此可以对它们进行 运行 sql 查询。目标是在两个上创建多维数据集维度(性别和部门)汇总了图书馆的图书借阅总数。使用命令

val cube=spark.sql("""
    select 
    borrowersTable.department,borrowersTable.gender,count(loansTable.bibno)
    from borrowersTable,loansTable
    where borrowersTable.bid=loansTable.bid
    group by borrowersTable.gender,borrowersTable.department with cube;
""")

我创建了具有以下结果的立方体:

然后使用命令

cube.write.format("csv").save("file:///....../data/cube")

Spark 创建一个名为 cube 的文件夹,其中包含 34 个名为 part*.csv 的文件,其中包含部门、性别和贷款总额(每组依据)的列。

这里的目标是以这种方式创建采用前两列(属性)名称的文件:对于 GroupBy (Attr1, Attr2),文件应命名为 Attr1_Attr2.

例如对于(经济学,M),文件应命名为 Economics_M。对于 (Mathematics, null) 它应该是 Mathematics_null 等等。任何帮助将不胜感激。

当您调用 df.write.format("...").save("...") 时,每个 Spark 执行器都会将其保存的分区保存到相应的 part* 文件中。这是存储和加载大文件的机制,你不能改变它。但是,您可以尝试以下替代方案,只要在您的情况下效果更好:

  1. 分区方式:
cube
  .write
  .partitionBy("department", "gender")
  .format("csv")
  .save("file:///....../data/cube")

这将创建名称类似于 department=Physics/gender=M 的子文件夹,其中仍然包含 part* 文件。此结构稍后可以加载回 Spark 并用于分区列的有效连接。

  1. 收集
val csvRows = cube
  .collect()
  .foreach {
    case Row(department: String, gender: String, _) => 
      // just the simple way to write CSV, you can use any CSV lib here as well
      Files.write(Paths.get(s"$department_$gender.csv"), s"$department,$gender".getBytes(StandardCharsets.UTF_8))
  }

如果您调用 collect(),您会在驱动程序端收到数据帧 Array[Row],然后您可以随心所欲地使用它。这种方法的重要限制是您的数据框应该适合驱动程序的内存。