我有一個處理分層資料的任務,但源資料在層次結構中包含錯誤,即:某些父子鏈接已損壞。我有一個重新建立這種連接的演算法,但我還沒有能夠自己實作它。示例:初始資料為
------ ---- ---------- -------
| NAME | ID | PARENTID | LEVEL |
------ ---- ---------- -------
| A1 | 1 | 2 | 1 |
| B1 | 2 | 3 | 2 |
| C1 | 18 | 4 | 3 |
| C2 | 3 | 5 | 3 |
| D1 | 4 | NULL | 4 |
| D2 | 5 | NULL | 4 |
| D3 | 10 | 11 | 4 |
| E1 | 11 | NULL | 5 |
------ ---- ---------- -------
示意圖如下:

如您所見,與 C1 和 D3 的連接在這里丟失。為了恢復連接,我需要對這個表應用以下演算法:
如果某些 NAME 的 ID 不在 PARENTID 列中(例如 ID = 18, 10),則創建一個帶有 LEVEL = (current LEVEL - 1) 和 PARENTID = (current ID) 的“父”行,并取 ID和 NAME 使得當前 ID < 來自上面 LEVEL 的節點的 ID。
結果必須是這樣的:
------ ---- ---------- -------
| NAME | ID | PARENTID | LEVEL |
------ ---- ---------- -------
| A1 | 1 | 2 | 1 |
| B1 | 2 | 3 | 2 |
| B1 | 2 | 18 | 2 |#
| C1 | 18 | 4 | 3 |
| C2 | 3 | 5 | 3 |
| C2 | 3 | 10 | 3 |#
| D1 | 4 | NULL | 4 |
| D2 | 5 | NULL | 4 |
| D3 | 10 | 11 | 4 |
| E1 | 11 | NULL | 5 |
------ ---- ---------- -------
其中帶有 # 的行 - 創建了新行。新架構如下所示:

關于如何在 spark/scala 中執行此演算法有什么想法嗎?謝謝!
uj5u.com熱心網友回復:
您可以createdRows從當前資料幀構建一個資料幀,并將其與當前資料幀結合以獲得最終資料幀。
您可以分createdRows幾個步驟構建此資料框:
- 第一步是獲取不在 PARENTID 列中的 ID(和 LEVEL)。您可以使用自左反連接來做到這一點。
- 然后,您將
ID列重命名為PARENTID并更新LEVEL列,將其減少1. - 然后,通過將新行
ID與NAME列上的輸入資料框連接起來,獲取新行的LEVEL列 - 最后,你應用你的條件
ID<PARENTID
您最終得到以下代碼,dataframe是帶有初始資料的資料框:
import org.apache.spark.sql.functions.col
val createdRows = dataframe
// if for some NAME the ID is not in the PARENTID column (like ID = 18, 10)
.select("LEVEL", "ID")
.filter(col("LEVEL") > 1) // Remove root node from created rows
.join(dataframe.select("PARENTID"), col("PARENTID") === col("ID"), "left_anti")
// then create a row with a 'parent' with LEVEL = (current LEVEL - 1) and PARENTID = (current ID)
.withColumnRenamed("ID", "PARENTID")
.withColumn("LEVEL", col("LEVEL") - 1)
// and take ID and NAME
.join(dataframe.select("NAME", "ID", "LEVEL"), Seq("LEVEL"))
// such that the current ID < ID of the node from the LEVEL above.
.filter(col("ID") < col("PARENTID"))
val result = dataframe
.unionByName(createdRows)
.orderBy("NAME", "PARENTID") // Optional, if you want an ordered result
在result資料框中你得到:
---- --- -------- -----
|NAME|ID |PARENTID|LEVEL|
---- --- -------- -----
|A1 |1 |2 |1 |
|B1 |2 |3 |2 |
|B1 |2 |18 |2 |
|C1 |18 |4 |3 |
|C2 |3 |5 |3 |
|C2 |3 |10 |3 |
|D1 |4 |null |4 |
|D2 |5 |null |4 |
|D3 |10 |11 |4 |
|E1 |11 |null |5 |
---- --- -------- -----
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/336041.html
