簡體   English   中英

Spark SQL-如何將 RelationalGroupedDataSet 轉換為 DataFrame

[英]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 1on_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM