【问题标题】:Spark - "partial" Window functionSpark - “部分”窗口函数
【发布时间】:2018-05-07 04:39:21
【问题描述】:

在 Spark 中尝试做“部分”窗口功能。

给定架构eventId、impressionTime、campaign、revenue,我想知道每个 evenId 的广告在过去 4 天内的总收入。

最后,我只在最后 3 天插入。所以我必须加载 7 天的数据(所以最早的事件有 4 天的窗口),问题是我还要计算最终范围之外的事件。

小例子: 我有 7 天的数据(第 1 天、第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天 7 天),并且在输出中只有天:7、6、5 是必需的。

我每 4 天需要一次窗口。所以我会整天加载并为他们做窗口功能。最后,我将只持续 3 天。

当然这是非常低效的,因为我也计算了窗口 第 4,3 天...

有没有对一些数据做窗口函数?

谢谢

【问题讨论】:

  • 为什么不先过滤掉数据?
  • 如果您的意思是添加过滤器 > 第 4 天,因为如果是这样,第 3、2、1 天将超出我的数据框,我将无法计算过去 4 天的收入4

标签: apache-spark apache-spark-sql spark-dataframe


【解决方案1】:

window functions 不提供只能计算输入数据日期子集(第 5、6 和 7 天)的聚合的方法。正如您所指出的,您无法进行预过滤,因为需要从第 1 天到第 4 天的数据来构建准确的窗口聚合。

如果您想使用 Spark 窗口函数,则必须在执行窗口聚合后过滤第 1 天到第 4 天。

计算窗口聚合的另一种方法是使用简单的连接,这可能更有效,具体取决于数据的大小、倾斜度和窗口函数的长度。这不需要后过滤,因为这是通过预过滤和连接条件处理的。

val df1 = spark.read.table("table1").filter(col("day").isin(Seq(5,6,7):_*))
val df2 = spark.read.table("table1").filter(col("day").isin(Seq(1,2,3,4,5,6,7):_*))

df1.
  join(df2, (df1("key1") === df2("key2")).and(df2("millisecond_ts").between(df1("millisecond_ts") - 1000*60*60*24*4, df1("millisecond_ts"))), "left")

【讨论】:

  • 谢谢,我将按照您的建议转入加入,而不是 window。然而,由于活动分布不均,我面临着倾斜加入问题。你也有克服这个问题的建议吗?
  • 使用 skew 加入 DataFrame 是一个非常难以解决的问题。解决方案取决于您可能愿意做出的问题和权衡。这是对连接优化的一个很好的总结:github.com/vaquarkhan/vk-wiki-notes/wiki/…
猜你喜欢
  • 1970-01-01
  • 2019-10-15
  • 2016-01-17
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多