【问题标题】:How to filter data using window functions in spark如何使用spark中的窗口函数过滤数据
【发布时间】:2016-12-16 18:57:07
【问题描述】:

我有以下数据:

rowid uid time code
   1  1      5    a
   2  1      6    b
   3  1      7    c
   4  2      8    a
   5  2      9    c
   6  2      9    c
   7  2     10    c
   8  2     11    a
   9  2     12    c

现在我想以这样一种方式过滤数据,以便我可以删除第 6 行和第 7 行,因为对于特定的 uid,我想在代码中只保留一个值为“c”的行

所以预期的数据应该是:

rowid uid time code
   1  1      5    a
   2  1      6    b
   3  1      7    c
   4  2      8    a
   5  2      9    c
   8  2     11    a
   9  2     12    c

我正在使用类似这样的窗口功能:

val window = Window.partitionBy("uid").orderBy("time")
val change = ((lag("code", 1).over(window) <=> "c")).cast("int")

这将帮助我们用代码“c”识别每一行。我可以扩展它以过滤掉行以获得预期的数据

【问题讨论】:

  • 您能说明一下您的要求吗?是否对于每个 UID,您只想为每个代码保留一行,还是只为代码“c”需要这样做?

标签: scala apache-spark spark-dataframe window-functions


【解决方案1】:

如果您只想删除 code = "c" 的行(每个 uid 的第一行除外),您可以尝试以下操作:

val window = Window.partitionBy("uid", "code").orderBy("time")
val result = df
  .withColumn("rank", row_number().over(window))
  .where(
    (col("code") !== "c") ||
    col("rank") === 1
  )
  .drop("rank")

根据新信息进行编辑:

val window = Window.partitionBy("uid").orderBy("time")
val result = df
  .withColumn("lagValue", coalesce(lag(col("code"), 1).over(window), lit("")))
  .where(
    (col("code") !== "c") ||
    (col("lagValue") !== "c")
  )
  .drop("lagValue")

【讨论】:

  • 在使用上述代码时,当我执行 partitionBy("uid", "code") 时,结果数据集不正确,因为这给出了以下结果:rowid uid 时间码
  • 抱歉,错过了上传整个评论。所以结果 df 类似于:在使用上面的代码时,当我执行 val window = Window.partitionBy("uid", "code")。 orderBy("time") df.withColumn("rank", row_number().over(window)) 结果数据集不正确,因为这给出了以下结果: rowid uid 时间码 rank 1 1 5 a 1 4 2 8 a 2 2 1 6 b 1 3 1 7 c 1 5 2 9 c 1 因此我放弃了 uid 上的分组
  • @hbabbar 你应该尝试完整的代码,而不仅仅是第一行:df.withColumn("rank", row_number().over(window)).where( (col("code") !== "c") || col("rank") === 1 ).drop("rank")
  • @hbabbar 我看不出你给我看的结果哪里错了。它似乎等于您的“预期”结果,但只是不正常。您可以使用.orderBy("rowid").orderBy("uid", "rowid") 轻松重新订购
  • 虽然 sn-p 按预期工作,但在功能需求方面有一些调整,我们也需要满足它。我在划分窗口时包含了“时间”列,但在这种情况下,它也会打印第 7 行(这不是我们想要的)。任何建议如何调整这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-10
  • 2018-02-24
  • 1970-01-01
  • 2021-12-14
  • 2016-02-28
相关资源
最近更新 更多