python - Groupby 和 collect_list 基于 PySpark 中的另一列维护顺序
问题描述
我有一个像这样的 PySpark 数据框,
+----------+------------+------------+------------+
| Name | dateCol1 | dateCol2 | dateCol3 |
+----------+------------+------------+------------+
| user1 | 2018-01-01 | 2018-01-10 | 2018-01-01 |
| user1 | 2018-01-11 | 2018-01-20 | 2018-01-01 |
| user2 | 2018-01-11 | 2018-01-20 | 2018-01-11 |
| user1 | 2019-01-21 | 2018-01-30 | 2018-01-01 |
+----------+------------+------------+------------+
我想在键、dateCol1 和 dateCol2 上对这个数据集进行分组,因此列名称上的 collect_list 。为此,我正在使用代码,
spark_df.groupBy('dateCol1', 'dateCol2').agg(F.collect_list('Name'))
在收集要列出的列时,我还想根据列 dateCol3 维护值的顺序。
例如,我想确保对于dateCol1 == '2018-01-11'
and dateCol2 == '2018-01-20'
,收集到列表我总是会得到[user1, user2]
(基于 dateCol3 的顺序)。
数据帧所需的输出是,
+------------+------------+----------------+
| dateCol1 | dateCol2 | List |
+------------+------------+----------------+
| 2018-01-01 | 2018-01-10 | [user1] |
| 2018-01-11 | 2018-01-20 | [user1, user2] |
| 2019-01-21 | 2018-01-30 | [user1] |
+------------+------------+----------------+
collect_list 默认情况下不会保持顺序,如何确保收集的列表是基于数据框中的另一个外部列排序的?
解决方案
你可以试试:
spark_df.orderBy('dateCol3', ascending=True).groupBy('dateCol1', 'dateCol2').agg(F.collect_list('Name'))
或者,虽然这有点矫枉过正,但您可以使用窗口:
from pyspark.sql import Window as w
spark_df.select('dateCol1', 'dateCol2', F.collect_list('Name').over(w.partitionBy(['dateCol1','dateCol2']).orderBy(F.col('dateCol3'))).alias('Name')).distinct()
推荐阅读
- django - 为restframework viewset action decorator添加一个新的装饰器
- angular - Angular:Header 中的事件使用 eventemitter/Observable 更新子组件
- selenium - 詹金斯硒集成
- imagemagick - 使用 Imagemagick,在图像外部添加水印,例如。批量使用填充?
- javascript - 解构具有附加属性的项目
- php - JWT Laravel 修改密码机制
- node.js - User.findOne 返回 null
- python - ValueError:从数据帧中提取 X 和 Y 时,代码需要是类似数组的整数
- assembly - 我可以将 CPU 中的寄存器用作堆栈机器的“堆栈顶部”吗?
- node.js - FindOneAndUpdate MongoDB 与 Mongoose 更新用户的个人资料不使用电子邮件?