通过某些列中的键快速拆分Spark数据帧并另存为不同的数据帧

时间:2019-05-09 08:50:45

标签: scala apache-spark apache-spark-sql

我有这样的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)。

1 个答案:

答案 0 :(得分:1)

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

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

您为什么不尝试呢?