簡體   English   中英

如何在spark中獲取兩個最接近的值 scala DataFrame

[英]How to get the two nearest values in spark scala DataFrame

大家好我是 Spark scala 的新手。我想使用 spark scala 通過分區找到最接近的值。我的輸入是這樣的:

例如第一行:值 1 在 value2 列中介於 2 和 7 之間

+--------+----------+----------+
|id      |value1    |value2    |
+--------+----------+----------+
|1       |3         |1         |
|1       |3         |2         |
|1       |3         |7         |

|2       |4         |2         |
|2       |4         |3         |
|2       |4         |8         |

|3       |5         |3         |
|3       |5         |6         |
|3       |5         |7         |
|3       |5         |8         |

我的 output 應該是這樣的:

+--------+----------+----------+
|id      |value1    |value2    |
+--------+----------+----------+
|1       |3         |2         |
|1       |3         |7         |

|2       |4         |3         |
|2       |4         |8         |

|3       |5         |3         |
|3       |5         |6         |

有人可以指導我如何解決這個問題。

我沒有提供您似乎想要學習的代碼答案,而是為您提供了偽代碼和參考,以便您自己找到答案。

  1. 對元素進行 分組(select id, value1)(使用collect_list在 value2 上聚合),以便您可以將所有 value2 收集到一個數組中。
  2. select (id, and (add( concat ) value1 to the collect_list array)) 排序數組
  3. 在數組中找到( array_position ) value1。
  4. splice數組。 檢索 ( array_position ) 結果之前的值和之后的值
  5. 如果數組少於 3 個元素做錯誤處理
  6. 現在數組中的最后一個值和數組中的第一個值是你的“最接近的數字”。

為此,您將需要window 個函數

val window = Window
  .partitionBy("id", "value1")
  .orderBy(asc("value2"))

val result = df
  .withColumn("prev", lag("value2").over(window))
  .withColumn("next", lead("value2").over(window))
  .withColumn("dist_prev", col("value2").minus(col("prev")))
  .withColumn("dist_next", col("next").minus(col("value2")))
  .withColumn("min", min(col("dist_prev")).over(window))
  .filter(col("dist_prev") === col("min") || col("dist_next") === col("min"))
  .drop("prev", "next", "dist_prev", "dist_next", "min")

我還沒有測試過它,所以將它更多地看作是概念的說明,而不是現成可用的示例。

這是這里發生的事情:

  • 首先,創建一個window來描述您的分組規則:我們希望行按前兩列分組,並按每組中的第三列排序。
  • 接下來,將prevnext列添加到 dataframe,它們分別包含組中上一行和下一行的value2列的值。 (組中第一行的prev將是 null,最后一行的next將是 null - 沒關系)。
  • 添加dist_prevdist_next分別包含value2prev一個值和next值之間的距離。 (請注意,每一行的dist_prev將與前一行的dist_next具有相同的值)。
  • 在每個組中找到dist_prev的最小值,並將其添加為min列(注意, dist_next的最小值在構造上是相同的,因此我們這里只需要一列)。
  • 篩選行,選擇dist_nextdist_prev中具有最小值的行。 除非有多行彼此之間的距離相同,否則這會找到最緊密的對 - 這種情況未在您的問題中考慮,因此我們不知道在這種情況下您想要什么樣的行為。 此實現將簡單地返回所有這些行。
  • 最后,刪除所有添加到 dataframe 的額外列,使其恢復到原來的形狀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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