【问题标题】:How to preserve default order in Spark dataframe after first order by inside window如何在窗口内第一次订购后保留Spark数据框中的默认顺序
【发布时间】:2021-02-11 20:27:39
【问题描述】:

我有一个包含 user_id, C1, f1,f2,f3 列的 spark 数据框。我想按user id 进行分区/分组,并且在组内我想保持关于C1 的顺序,我已经成功完成了,但是在 C1 排序之后,我想保持默认顺序的其余部分.

例如。以下是特定用户的数据框(例如在user_id == 1 上应用的文件管理器)

+--------+-------------+-------------+--------+------------------
|User_id | C1          |f1           |f2      | f3              |
+--------+-------------+-------------+----------------------------
|1       | 6420048     |B1           |TC      |19               |
|1       | 21610696    |U0           |PC      |135              |
|1       | 21610700    |U0           |IP      |135              |
|1       | 28975032    |B1           |CU      |20               |
|1       | 46422270    |U3           |CU      |73               |
|1       | 68008129    |U1           |RM      |135              |
|1       | 68008129    |U1           |CM      |135              |
|1       | 68008129    |U1           |CM      |129              |
|1       | 68008129    |U1           |PM      |130              |
|1       | 68023980    |U1           |PM      |129              |
|1       | 68023980    |U1           |CM      |135              |
|1       | 68023980    |U1           |PM      |135              |
|1       | 68023980    |U1           |PM      |130              |
+--------+---------+-------------+--------+---------------------

我现在正在做的是,我按user_id 分区并按C1 排序。我正在使用的窗口是

 Window.partitionBy('user_id').orderBy('C1')

为了解释我的问题,我添加了一个列order,如下所示

 df= df.withColumn('order',row_number().over(w))

但是在窗口顺序为 C1 提供正确顺序(对于每个用户)但 C1 顺序未保留为默认顺序后,请注意对于 C1 列值68023980,它现在具有 f2 序列 [CM,PM,PM,PM] 但它应该有[PM,CM,PM,PM] 和C1 68008129 我有f2 [PM,CM,PM] 而不是[CM,PM,PM]。其他列 (f3) 也是如此。

这是当前输出的示例

+--------+---------+-------------+--------+-------+----------
|User_id | C1      |f1           |f2      | f3    | order     |
+--------+-------------+--------+-----------------+-----------
|1       | 6420048 |B1           |TC      |19     |    1      |
|1       | 21610696|U0           |PC      |135    |    2      |
|1       | 21610700|U0           |IP      |135    |    3      |
|1       | 28975032|B1           |CU      |20     |    4      |
|1       | 46422270|U3           |CU      |73     |    5      |
|1       | 68008129|U1           |PM      |129    |    6      |
|1       | 68008129|U1           |CM      |135    |    7      |
|1       | 68008129|U1           |PM      |130    |    8      |
|1       | 68008129|U1           |PM      |135    |    9      |
|1       | 68023980|U1           |CM      |135    |    10     |
|1       | 68023980|U1           |PM      |130    |    11     |
|1       | 68023980|U1           |PM      |129    |    12     |
|1       | 68023980|U1           |PM      |135    |    13     |
+--------+-------------+--------+-----------------+-----------

C1下单后如何保持默认顺序?

【问题讨论】:

  • 在应用 Window 聚合函数之前添加 monotonically_increasing_id()。
  • Jxc,谢谢您的评论,它是否与 row_number 不同,因为在这种情况下,订单列不正确,就像我在答案中提到的那样,任何细节都会有所帮助。
  • 它不是聚合函数,不会触发数据混洗。窗口上的 row_number() 必须处理已经洗牌的数据。
  • 谢谢,我是按单调递增的方式订购的:)

标签: python apache-spark pyspark apache-spark-sql aggregate-functions


【解决方案1】:

在 cmets 中 @Jxc 的指导下,我可以在窗口操作之前添加 monotonically_increasing_id() 来帮助它。

这是一个例子

df= df.withColumn("idx", monotonically_increasing_id())
w= Window.partitionBy("user-id").orderBy('C1','idx')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2014-05-03
    • 1970-01-01
    • 2018-05-12
    • 2017-03-09
    相关资源
    最近更新 更多