collect_list()是否维护行的相对排序?

时间:2017-06-09 01:42:00

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

想象一下,我有以下DataFrame df:

+---+-----------+------------+
| id|featureName|featureValue|
+---+-----------+------------+
|id1|          a|           3|
|id1|          b|           4|
|id2|          a|           2|
|id2|          c|           5|
|id3|          d|           9|
+---+-----------+------------+

想象一下,我跑:

df.groupBy("id")
  .agg(collect_list($"featureIndex").as("idx"),
       collect_list($"featureValue").as("val"))

保证那" idx"和" val"将被汇总并保持相对顺序?即。

GOOD                   GOOD                   BAD
+---+------+------+    +---+------+------+    +---+------+------+
| id|   idx|   val|    | id|   idx|   val|    | id|   idx|   val|
+---+------+------+    +---+------+------+    +---+------+------+
|id3|   [d]|   [9]|    |id3|   [d]|   [9]|    |id3|   [d]|   [9]|
|id1|[a, b]|[3, 4]|    |id1|[b, a]|[4, 3]|    |id1|[a, b]|[4, 3]|
|id2|[a, c]|[2, 5]|    |id2|[c, a]|[5, 2]|    |id2|[a, c]|[5, 2]|
+---+------+------+    +---+------+------+    +---+------+------+

注意:例如这是不好的,因为id1 [a,b]应该与[3,4](而不是[4,3])相关联。对于id2

也是如此

1 个答案:

答案 0 :(得分:10)

我认为你可以依赖"他们的相对顺序" ,因为Spark按顺序逐行遍历行(并且通常不会重新排序如果没有明确需要,则订购行。)

如果您关注订单,请在执行groupBy之前使用struct函数合并这两列。

  

struct(colName:String,colNames:String *):Column 创建一个组成多个输入列的新struct列。

您还可以使用monotonically_increasing_id函数对记录进行编号,并使用它与其他列配对(可能使用struct):

  

monotonically_increasing_id():Column 生成单调递增的64位整数的列表达式。

     

生成的ID保证单调增加且唯一,但不是连续的。