我有一个来自处理部分的数据框,看起来像:
+---------+------+-----------+
|Time |group |value |
+---------+------+-----------+
| 28371| 94| 906|
| 28372| 94| 864|
| 28373| 94| 682|
| 28374| 94| 574|
| 28383| 95| 630|
| 28384| 95| 716|
| 28385| 95| 913|
我想为每个组取(最长时间的值-最短时间的值),以得到以下结果:
+------+-----------+
|group | value |
+------+-----------+
| 94| -332|
| 95| 283|
预先感谢您的帮助
答案 0 :(得分:2)
df.groupBy("groupCol").agg(max("value")-min("value"))
根据OP编辑的问题,以下是在PySpark中执行此操作的方法。想法是按每组时间的升序和降序计算行号,并将这些值相减。
from pyspark.sql import Window
from pyspark.sql import functions as func
w_asc = Window.partitionBy(df.groupCol).orderBy(df.time)
w_desc = Window.partitionBy(df.groupCol).orderBy(func.desc(df.time))
df = df.withColumn(func.row_number().over(w_asc).alias('rnum_asc')) \
.withColumn(func.row_number().over(w_desc).alias('rnum_desc'))
df.groupBy(df.groupCol) \
.agg((func.max(func.when(df.rnum_desc==1,df.value))-func.max(func.when(df.rnum_asc==1,df.value))).alias('diff')).show()
如果Spark SQL中提供了窗口功能first_value
,那会更容易。使用SQL解决此问题的通用方法是
select distinct groupCol,diff
from (
select t.*
,first_value(val) over(partition by groupCol order by time) -
first_value(val) over(partition by groupCol order by time desc) as diff
from tbl t
) t