scala - 通过某些列中的键快速拆分 Spark 数据帧并保存为不同的数据帧
问题描述
我有 Spark 2.3 非常大的数据框,如下所示:
-------------------------
| col_key | col1 | col2 |
-------------------------
| AA | 1 | 2 |
| AB | 2 | 1 |
| AA | 2 | 3 |
| AC | 1 | 2 |
| AA | 3 | 2 |
| AC | 5 | 3 |
-------------------------
我需要通过 col_key 列中的值“拆分”这个数据帧,并将每个拆分的部分保存在单独的 csv 文件中,所以我必须得到更小的数据帧,比如
-------------------------
| col_key | col1 | col2 |
-------------------------
| AA | 1 | 2 |
| AA | 2 | 3 |
| AA | 3 | 2 |
-------------------------
和
-------------------------
| col_key | col1 | col2 |
-------------------------
| AC | 1 | 2 |
| AC | 5 | 3 |
-------------------------
到目前为止。我需要将每个结果数据框保存为不同的 csv 文件。
键的数量不大(20-30),但数据的总数是(约 2 亿条记录)。
我有解决方案,在循环中选择数据的每个部分,然后保存到文件中:
val keysList = df.select("col_key").distinct().map(r => r.getString(0)).collect.toList
keysList.foreach(k => {
val dfi = df.where($"col_key" === lit(k))
SaveDataByKey(dfi, path_to_save)
})
它工作正常,但这个解决方案的坏问题是每个关键的数据选择都完全通过整个数据帧,它得到了太多的时间。我认为必须是更快的解决方案,我们只通过一次数据帧,在此期间将每条记录放入“严格”的结果数据帧(或直接放入单独的文件)。但我不知道该怎么做:) 可能有人对此有想法?
此外,我更喜欢使用 Spark 的 DataFrame API,因为它提供了最快的数据处理方式(因此,如果可能的话,使用 RDD 是不可取的)。
解决方案
您需要按列分区并保存为 csv 文件。每个分区保存为一个文件。
yourDF
.write
.partitionBy("col_key")
.csv("/path/to/save")
你为什么不试试这个?
推荐阅读
- docker - 在wsl2上同步windows和docker太慢了
- python - 从文件中按顺序打印前 3 和后 3 的分数
- javascript - 尝试为用户订阅推送通知时,我的服务人员需要刷新才能激活
- mysql - 在没有与 MySQL Work Bench 事先连接的情况下,Spring Boot 无法连接到 MySQL 服务器
- sql - SQL Server - 如何记录哪些条目是重复的?
- c# - 如何在 foreach 中捕获每个单元格;因此,当单元格为空时,它会显示错误文本
- firebase - Firebase 身份验证期间参数列表后未捕获的 SyntaxError: missing )
- html - 为什么所有的附属市场都不在附属链接中使用 (rel="noreferrer noopener")?
- performance - Ocaml:使用通配符是否比在模式匹配中使用变量更有效?
- azure-virtual-network - Azure 容器实例 (ACI) 部署到虚拟网络失败(区域:西欧)