Dataframe pySpark-在滚动窗口中获取最大值行
我有一个pyspark数据框架,下面是示例行。我试图在10分钟内得到最大平均值。我正在尝试使用窗口函数,但无法实现结果 这是我的30分钟随机数据的数据帧。我希望输出3行,每10分钟1行Dataframe pySpark-在滚动窗口中获取最大值行,dataframe,apache-spark,pyspark,Dataframe,Apache Spark,Pyspark,我有一个pyspark数据框架,下面是示例行。我试图在10分钟内得到最大平均值。我正在尝试使用窗口函数,但无法实现结果 这是我的30分钟随机数据的数据帧。我希望输出3行,每10分钟1行 +-------------------+---------+ | event_time|avg_value| +-------------------+---------+ |2019-12-29 00:01:00| 9.5| |2019-12-29 00:02:00| 9.
+-------------------+---------+
| event_time|avg_value|
+-------------------+---------+
|2019-12-29 00:01:00| 9.5|
|2019-12-29 00:02:00| 9.0|
|2019-12-29 00:04:00| 8.0|
|2019-12-29 00:06:00| 21.0|
|2019-12-29 00:08:00| 7.0|
|2019-12-29 00:11:00| 8.5|
|2019-12-29 00:12:00| 11.5|
|2019-12-29 00:14:00| 8.0|
|2019-12-29 00:16:00| 31.0|
|2019-12-29 00:18:00| 8.0|
|2019-12-29 00:21:00| 8.0|
|2019-12-29 00:22:00| 16.5|
|2019-12-29 00:24:00| 7.0|
|2019-12-29 00:26:00| 14.0|
|2019-12-29 00:28:00| 7.0|
+-------------------+---------+
我正在使用下面的代码
window_spec = Window.partitionBy('event_time').orderBy('event_time').rangeBetween(-60*10,0)
new_df = data.withColumn('rank', rank().over(window_spec))
new_df.show()
但此代码给了我以下错误:
pyspark.sql.utils.AnalysisException: 'Window Frame specifiedwindowframe(RangeFrame, -600, currentrow$()) must match the required frame specifiedwindowframe(RowFrame, unboundedpreceding$(), currentrow$());'
我期望的输出是
+-------------------+---------+
| event_time|avg_value|
+-------------------+---------+
|2019-12-29 00:06:00| 21.0|
|2019-12-29 00:16:00| 31.0|
|2019-12-29 00:22:00| 16.5|
+-------------------+---------+
有人能帮我吗
TIA。您可以使用带有
窗口的
from pyspark.sql import functions as F
df.groupBy(F.window("event_time","10 minutes"))\
.agg(F.max("avg_value").alias("avg_value")).show()
#+--------------------+---------+
#| window|avg_value|
#+--------------------+---------+
#|[2019-12-29 00:20...| 16.5|
#|[2019-12-29 00:10...| 31.0|
#|[2019-12-29 00:00...| 21.0|
#+--------------------+---------+
要获得所需的事件时间
列的精确输出,您可以使用收集列表
,数组排序
和元素(spark2.4+)
更新
:
df.groupBy(F.window("event_time","10 minutes"))\
.agg(F.collect_list(F.struct("event_time","avg_value")).alias("event_time")\
,F.max("avg_value").alias("avg_value"))\
.withColumn("event_time", F.expr("""filter(event_time, x-> x.avg_value=avg_value)"""))\
.select((F.col("event_time.event_time")[0]).alias("event_time"),"avg_value").orderBy("event_time").show()
#+-------------------+---------+
#| event_time|avg_value|
#+-------------------+---------+
#|2019-12-29 00:06:00| 21.0|
#|2019-12-29 00:16:00| 31.0|
#|2019-12-29 00:22:00| 16.5|
#+-------------------+---------+
你的数据
解决方案
谢谢这真的很有帮助。我唯一能看到的是最大值与事件时间不匹配,例如:对于21-30分钟窗口,第22分钟的最大值为16.5,而不是第26分钟。当我在整个数据帧上运行这段代码时,我在几个地方看到了这一点。非常好用。。!!谢谢。我会尽力理解你的作品。我使用了高阶函数
过滤器
遍历两列的结构,然后获得所需的时间。看看这些功能,它们非常有用
df.groupBy(F.window("event_time","10 minutes"))\
.agg(F.collect_list(F.struct("event_time","avg_value")).alias("event_time")\
,F.max("avg_value").alias("avg_value"))\
.withColumn("event_time", F.expr("""filter(event_time, x-> x.avg_value=avg_value)"""))\
.select((F.col("event_time.event_time")[0]).alias("event_time"),"avg_value").orderBy("event_time").show()
#+-------------------+---------+
#| event_time|avg_value|
#+-------------------+---------+
#|2019-12-29 00:06:00| 21.0|
#|2019-12-29 00:16:00| 31.0|
#|2019-12-29 00:22:00| 16.5|
#+-------------------+---------+
data = [
('2019-12-29 00:01:00', 9.5,),
('2019-12-29 00:02:00', 9.0,),
('2019-12-29 00:04:00', 8.0,),
('2019-12-29 00:06:00', 21.0,),
('2019-12-29 00:08:00', 7.0,),
('2019-12-29 00:11:00', 8.5,),
('2019-12-29 00:12:00', 11.5,),
('2019-12-29 00:14:00', 8.0,),
('2019-12-29 00:16:00', 31.0,),
('2019-12-29 00:18:00', 8.0,),
('2019-12-29 00:21:00', 8.0,),
('2019-12-29 00:22:00', 16.5,),
('2019-12-29 00:24:00', 7.0,),
('2019-12-29 00:26:00', 14.0,),
('2019-12-29 00:28:00', 7.0,),
]
df = spark.createDataFrame(data, ['event_time', 'avg_value'])
from pyspark.sql import Window
from pyspark.sql.functions import window, max, col
w = Window().partitionBy('group_col')
(
df.
withColumn(
'group_col',
window('event_time', '10 minutes')
).
withColumn(
'max_val',
max(col('avg_value')).over(w)
).
where(
col('avg_value') == col('max_val')
).
drop(
'max_val',
'group_col'
).
orderBy('event_time').
show(truncate=False)
)
+-------------------+---------+
|event_time |avg_value|
+-------------------+---------+
|2019-12-29 00:06:00|21.0 |
|2019-12-29 00:16:00|31.0 |
|2019-12-29 00:22:00|16.5 |
+-------------------+---------+