有没有办法使用名称不同于 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* 文件中。这是存储和加载大文件的机制,你不能改变它。但是,您可以尝试以下替代方案,只要在您的情况下效果更好:
- 分区方式:
cube
.write
.partitionBy("department", "gender")
.format("csv")
.save("file:///....../data/cube")
这将创建名称类似于 department=Physics/gender=M
的子文件夹,其中仍然包含 part* 文件。此结构稍后可以加载回 Spark 并用于分区列的有效连接。
- 收集
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]
,然后您可以随心所欲地使用它。这种方法的重要限制是您的数据框应该适合驱动程序的内存。
我使用 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* 文件中。这是存储和加载大文件的机制,你不能改变它。但是,您可以尝试以下替代方案,只要在您的情况下效果更好:
- 分区方式:
cube
.write
.partitionBy("department", "gender")
.format("csv")
.save("file:///....../data/cube")
这将创建名称类似于 department=Physics/gender=M
的子文件夹,其中仍然包含 part* 文件。此结构稍后可以加载回 Spark 并用于分区列的有效连接。
- 收集
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]
,然后您可以随心所欲地使用它。这种方法的重要限制是您的数据框应该适合驱动程序的内存。