[英]How can you apply filter for a RelationalGroupedDataset class from apache.spark.sql using Scala?
[英]Spark SQL- How to Convert RelationalGroupedDataSet to DataFrame
你好,
在我的問題中,我需要對 DataFrame 進行分組,為每個組應用業務邏輯,最后在此基礎上發出一個新的 DataFrame。 為了詳細描述,有一個device_dataframe
包含設備何時打開( on
)和關閉( off
)的時間戳。
+---------+----- +--------------------+
|device_id|state | d_ts |
+---------+----- +--------------------+
|1 |on |2020-09-01 16:14:58 |
|1 |off |2020-09-10 16:14:58 |
|1 |on |2020-09-19 16:14:58 |
|2 |on |2020-09-20 16:14:58 |
|2 |off |2020-10-03 16:14:58 |
|4 |on |2020-09-20 16:14:58 |
|5 |off |2020-09-20 16:14:58 |
+---------+-----+-------+-------------+
另一方面,有一個 DataFrame 包含事件信息,包括其時間戳和相應的設備。
+-----+---------+--------------------+
|e_id |device_id| e_ts |
+-----+---------+--------------------+
|1 |1 |2020-09-20 16:14:58 |
|2 |2 |2020-10-08 09:19:55 |
|3 |4 |2020-11-01 12:15:37 |
|4 |5 |2020-10-08 01:35:08 |
+-----+---------+-------+------------+
以下是兩個 DataFrame 的連接示例:
+---------+-----+--------------------+------+--------------------+
|device_id|e_id | e_ts |state | d_ts |
+---------+-----+--------------------+------+--------------------+
|1 |1 |2020-09-20 16:14:58 |on |2020-09-01 16:14:58 |
|1 |1 |2020-09-20 16:14:58 |off |2020-09-10 16:14:58 |
|1 |1 |2020-09-20 16:14:58 |on |2020-09-19 16:14:58 |
|2 |2 |2020-10-08 09:19:55 |on |2020-09-20 16:14:58 |
|2 |2 |2020-10-08 09:19:55 |off |2020-10-03 16:14:58 |
|4 |3 |2020-11-01 12:15:37 |on |2020-09-20 16:14:58 |
|5 |4 |2020-10-08 01:35:08 |off |2020-09-20 16:14:58 |
+---------+-----+-------+--------------------+------+------------+
我最終需要找到的是其對應設備on
時發生的事件信息。 例如在上表的情況下,event_id 1
是有效的,因為它發生on
2020-09-20 16:14:58
並且它的設備從2020-09-19 16:14:58
,並且 event_id 2
無效,因為它的設備在2020-10-03 16:14:58
被關閉並且從未再次打開,依此類推。
Update1 :我需要的其他信息是設備在事件發生之前被設置為on
的次數,結果如下表:
+---------+-----+----------+-------------------+
|device_id|e_id | on_count | e_ts |
+---------+-----+----------+-------------------+
|1 |1 | 2 |2020-09-20 16:14:58|
|4 |3 | 1 |2020-11-01 12:15:37|
+---------+-----+----------+-------------------+
在上表中,事件 id 1
的on_count
值為 2,因為當它發生在2020-09-20 16:14:58
時,device_id 1
已經被打開了兩次。
我執行以下操作以根據設備對連接表進行分組:
val grouped = eventDF
.join(deviceDF, "device_id")
.groupBy("device_id")
這導致RelationalGroupedDataSet
。 現在我需要將邏輯應用於每個組並發出結果 DataFrame 但我沒有找到解決方案。 我檢查了UDAF
,但我發現它在我的情況下不起作用。
我知道如何使用 RDD API 來解決這個問題,但我想找到它的Column API方法。 任何幫助或建議將不勝感激。
謝謝
您可以使用以下邏輯獲取每個device_id
的最后一個 state,並過濾最后一個 state 所在on
行:
import org.apache.spark.sql.expressions.Window
val result = eventDF
.join(deviceDF, "device_id")
.withColumn(
"last_state",
max(when($"d_ts" < $"e_ts", array($"d_ts", $"state"))).over(Window.partitionBy("device_id", "e_id"))(1)
)
.withColumn(
"on_count",
count(when($"state" === "on" && $"d_ts" < $"e_ts", 1)).over(Window.partitionBy("device_id", "e_id"))
)
.filter("last_state = 'on'")
.select("device_id", "e_id", "on_count", "e_ts")
.distinct
result.show
+---------+----+--------+-------------------+
|device_id|e_id|on_count| e_ts|
+---------+----+--------+-------------------+
| 1| 1| 2|2020-09-20 16:14:58|
| 4| 3| 1|2020-11-01 12:15:37|
+---------+----+--------+-------------------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.