如何对pyspark中每个组内的变量进行排序?
我正在尝试为每个如何对pyspark中每个组内的变量进行排序?,pyspark,pyspark-sql,Pyspark,Pyspark Sql,我正在尝试为每个id使用另一列ts对值val进行排序 # imports from pyspark.sql import functions as F from pyspark.sql import SparkSession as ss import pandas as pd # create dummy data pdf = pd.DataFrame( [['2',2,'cat'],['1',1,'dog'],['1',2,'cat'],['2',3,'cat'],['2',4,'dog']
id
使用另一列ts
对值val
进行排序
# imports
from pyspark.sql import functions as F
from pyspark.sql import SparkSession as ss
import pandas as pd
# create dummy data
pdf = pd.DataFrame( [['2',2,'cat'],['1',1,'dog'],['1',2,'cat'],['2',3,'cat'],['2',4,'dog']] ,columns=['id','ts','val'])
sdf = ss.createDataFrame( pdf )
sdf.show()
+---+---+---+
| id| ts|val|
+---+---+---+
| 2| 2|cat|
| 1| 1|dog|
| 1| 2|cat|
| 2| 3|cat|
| 2| 4|dog|
+---+---+---+
您可以按
id
进行聚合,并按ts
进行排序:
sorted_sdf = ( sdf.groupBy('id')
.agg( F.sort_array( F.collect_list( F.struct( F.col('ts'), F.col('val') ) ), asc = True)
.alias('sorted_col') )
)
sorted_sdf.show()
+---+--------------------+
| id| sorted_col|
+---+--------------------+
| 1| [[1,dog], [2,cat]]|
| 2|[[2,cat], [3,cat]...|
+---+--------------------+
然后,我们可以分解此列表:
explode_sdf = sorted_sdf.select( 'id' , F.explode( F.col('sorted_col') ).alias('sorted_explode') )
explode_sdf.show()
+---+--------------+
| id|sorted_explode|
+---+--------------+
| 1| [1,dog]|
| 1| [2,cat]|
| 2| [2,cat]|
| 2| [3,cat]|
| 2| [4,dog]|
+---+--------------+
将排序的元组分解为两个:
detupled_sdf = explode_sdf.select( 'id', 'sorted_explode.*' )
detupled_sdf.show()
+---+---+---+
| id| ts|val|
+---+---+---+
| 1| 1|dog|
| 1| 2|cat|
| 2| 2|cat|
| 2| 3|cat|
| 2| 4|dog|
+---+---+---+
现在,对于每个
id
,我们的原始数据帧按ts
排序 您不能将多个参数传递给sort()
?我很确定,sorted\u sdf=sdf.sort('id','ts')
将实现所需的结果,而无需聚合和分解。是的,sort
在技术上适用于此处的虚拟数据。然而,对于我的实际用例,我需要公开中间步骤并执行一些额外的过程。此外,sort
如果您不需要id
sorted,成本会更高,对吗?我不能百分之百肯定地说,但它似乎比分区、收集列表、排序数组更便宜,而且爆炸。嗯,但即使如此,据我所知,这些东西比全局排序更具并行性。嘿,谢谢你的回答,它确实帮助了我。有没有一种更优雅的方法来链接所有这些函数,而不是F.sort\u数组(F.collect\u list(F.struct(F.col('ts')、F.col('val'))、asc=True)
?答案很棒。谢谢