簡體   English   中英

使用 Apache Spark 或其他類似解決方案返回按天分配的總和的有效方法是什么?

[英]What is an effective way to return sum distributed by days using Apache Spark or another similiar solution?

假設我們有許多具有屬性的記錄:id、start_day、end_date、sum。 這些記錄具有由開始日期和結束日期定義的不同時期,並且這些時期的長度不同。

我需要得到一組記錄作為結果,例如:

id, part_id, date, sum/(end_date - start_date)
...

對於每一天和每個時期。 因此,每條記錄的總和分布在屬於該記錄期間的所有日期之間。

例如,如果我有初始集:

1, 2022-12-01, 2022-12-03, 12
2, 2022-12-05, 2022-12-10, 100

我希望得到這個:

1, 1, 2022-12-01, 6
1, 2, 2022-12-02, 6
2, 1, 2022-12-05, 20
2, 2, 2022-12-06, 20
2, 3, 2022-12-07, 20
2, 4, 2022-12-08, 20
2, 5, 2022-12-09, 20

我正在研究實施數據分析解決方案的可能方法。 我知道有一種方法可以在 RDBMS 中使用 SQL 來做到這一點,但是如果有一種方法可以使用 Apache Spark 或其他方法讓它變得更好,我會開始更深入地挖掘。

我嘗試在 RDBMS 中優化 SQL 查詢,並意識到讓這樣的查詢快速運行對開發人員和 Postgres 來說都是一項艱巨的挑戰。 我嘗試使用 Java 的 MapReduce 方法,它運行良好並且看起來可擴展,但我不想在應用程序級別運行這樣的邏輯。

如果這是一個復雜的問題,我不是在尋找確切的答案,我真的很感激任何關於什么是處理此類查詢的最佳工具的意見。 謝謝!

您可以使用此表達式生成 2 個日期之間的所有日期:

“序列(開始日、結束日、間隔 1 天)”

這將適用於 spark 2.4+ ,然后使用 datediff 計算 start_date 和 end_date 之間的天數,然后將總和除以該數字:

import spark.implicits._
val df = Seq(
  (1, "2022-12-01", "2022-12-03", 12),
  (2, "2022-12-05", "2022-12-10", 100),
).toDF("id", "start_day", "end_date", "sum")

val w = Window.partitionBy("id").orderBy("date")
df.withColumn("start_day", col("start_day").cast("date"))
  .withColumn("end_date", date_add(col("end_date").cast("date"), -1))
  .withColumn("datesDiff", datediff(col("end_date"), col("start_day")) + 1)
  .withColumn("date", explode(expr("sequence(start_day, end_date, interval 1 day)")))
  .withColumn("idx", row_number().over(w))
  .withColumn("sum", col("sum").divide(col("datesDiff")))
  .select("id", "idx", "date", "sum")
  .show(false)


+---+---+----------+----+
|id |idx|date      |sum |
+---+---+----------+----+
|1  |1  |2022-12-01|6.0 |
|1  |2  |2022-12-02|6.0 |
|2  |1  |2022-12-05|20.0|
|2  |2  |2022-12-06|20.0|
|2  |3  |2022-12-07|20.0|
|2  |4  |2022-12-08|20.0|
|2  |5  |2022-12-09|20.0|
+---+---+----------+----+

暫無
暫無

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

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