首页 > 解决方案 > 通过某些列中的键快速拆分 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 是不可取的)。

标签: scalaapache-sparkapache-spark-sql

解决方案


您需要按列分区并保存为 csv 文件。每个分区保存为一个文件。

yourDF
  .write
  .partitionBy("col_key")
  .csv("/path/to/save")

你为什么不试试这个?


推荐阅读