collect_list() 是不是保持行的相对顺序?

Posted

技术标签:

【中文标题】collect_list() 是不是保持行的相对顺序?【英文标题】:Does collect_list() maintain relative ordering of rows?collect_list() 是否保持行的相对顺序? 【发布时间】:2017-06-09 01:41:59 【问题描述】:

假设我有以下 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】:

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

如果您关心顺序,请在执行groupBy 之前使用struct 函数合并这两列。

struct(colName: String, colNames: String*): Column 创建一个包含多个输入列的新结构列。

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

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

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

【讨论】:

因此 Spark DataFrame “水平”而不是“垂直”分布数据的处理。即一个执行者总是会收到整行,而不仅仅是几列? 是的。行始终完整地位于一个执行器/节点上。

以上是关于collect_list() 是不是保持行的相对顺序?的主要内容,如果未能解决你的问题,请参考以下文章

HiveQL collect_list保持顺序小记

PySpark 使用 collect_list 收集不同长度的数组

当元素从相对位置定位到固定位置但腾出的空间保持固定高度时,是不是会发生页面重排

顺时针打印矩阵

如何保持鼠标相对于屏幕的位置并忽略组件旋转?

通过 Spark SQL 实现 `collect_list`