如何按列划分为CSV格式的DataFrame时保持顺序?

时间:2018-08-09 15:34:07

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

我对DataFrame的行进行排序,然后将其写到磁盘中:

df.
  orderBy("foo").
  write.
  partitionBy("bar", "moo").
  option("compression", "gzip").
  csv(outDir)

当我查看生成的.csv.gz文件时,不会保留它们的顺序。这是Spark这样做的方式吗?当使用分区将DF写入磁盘时,是否可以保留顺序?

编辑:更精确地说:不是关闭CSV的顺序,而是关闭其中的顺序。假设在df.orderBy之后有以下内容(为简单起见,我现在仅按一列进行分区):

foo | bar | baz
===============
  1 |   1 |   1
  1 |   2 |   2
  1 |   1 |   3
  2 |   3 |   4
  2 |   1 |   5
  3 |   2 |   6
  3 |   3 |   7
  4 |   2 |   9
  4 |   1 |  10

我希望它是这样的,例如用于文件夹bar=1中的文件:

part-00000-NNN.csv.gz:

1,1
1,3
2,5

part-00001-NNN.csv.gz:

3,8
4,10

但它是什么样的:

part-00000-NNN.csv.gz:

1,1
2,5
1,3

part-00001-NNN.csv.gz:

4,10
3,8

1 个答案:

答案 0 :(得分:0)

已经有一段时间了,但我又目睹了这一点。我终于遇到了解决方法。

假设您的架构如下:

  • 时间:bigint
  • 频道:字符串
  • 值:double

如果您这样做:

df.sortBy("time").write.partitionBy("channel").csv("hdfs:///foo")

各个part-*文件中的时间戳都被扔掉了。

如果您这样做:

df.sortBy("channel", "time").write.partitionBy("channel").csv("hdfs:///foo")

顺序正确。

我认为这与改组有关。因此,作为一种解决方法,我现在要按我要对数据进行分区的列进行排序,然后再按我要对各个文件进行排序的列进行排序。