【发布时间】:2016-06-12 19:35:02
【问题描述】:
这个问题并不新鲜,但我在 Spark 中发现了令人惊讶的行为。我需要将一列行 ID 添加到 DataFrame。我使用了 DataFrame 方法 monotonically_increasing_id() 它确实给了我一个额外的唯一行 ID 列(顺便说一下,它们不是连续的,但是是唯一的)。
我遇到的问题是,当我过滤 DataFrame 时,结果 DataFrame 中的行 ID 被重新分配。这两个 DataFrame 如下所示。
-
第一个是初始DataFrame,添加行ID如下:
df.withColumn("rowId", monotonically_increasing_id()) 第二个 DataFrame 是通过
df.filter(col("P"))在 col P 上过滤后获得的。
custId 169 的 rowId 说明了问题,在初始 DataFrame 中为 5,但在过滤掉 custId 169 时,rowId (5) 被重新分配给 custmId 773!我不知道为什么这是默认行为。
我希望rowIds 具有“粘性”;如果我从 DataFrame 中删除行,我不希望它们的 ID “重复使用”,我希望它们与它们的行一起消失。有可能这样做吗?我没有看到任何从 monotonically_increasing_id 方法请求此行为的标志。
+---------+--------------------+-------+
| custId | features| P |rowId|
+---------+--------------------+-------+
|806 |[50,5074,...| true| 0|
|832 |[45,120,1...| true| 1|
|216 |[6691,272...| true| 2|
|926 |[120,1788...| true| 3|
|875 |[54,120,1...| true| 4|
|169 |[19406,21...| false| 5|
after filtering on P:
+---------+--------------------+-------+
| custId| features| P |rowId|
+---------+--------------------+-------+
| 806|[50,5074,...| true| 0|
| 832|[45,120,1...| true| 1|
| 216|[6691,272...| true| 2|
| 926|[120,1788...| true| 3|
| 875|[54,120,1...| true| 4|
| 773|[3136,317...| true| 5|
【问题讨论】:
-
你能分享你生成两个示例数据帧的完整代码吗?就其价值而言,这可能是由于 SQL 查询优化发生的,其中“独立”映射阶段可能会重新排列。
-
Hamel,除了我发布的内容之外,真的没有其他转换或动作。显示的数据帧是 df.show() 的结果。您可以非常轻松地重新创建此行为,创建一个数据框并添加一个行 ID 列,然后向其中添加一个随机布尔列。然后对该列进行过滤,看看你从单调增加中获得的行 ID 是如何“重复使用”的。
-
@Kai 我实际上要补充一点,重现它的最简单方法是仅使用单个分区。
-
Spark 跟踪器上的问题:SPARK-14241
-
感谢尼克接受这个。
标签: apache-spark dataframe apache-spark-sql