gpt4 book ai didi

apache-spark - 如何在组中找到第一个非空值? (使用数据集api进行二次排序)

转载 作者:行者123 更新时间:2023-12-04 12:17:23 24 4
gpt4 key购买 nike

我正在处理一个表示事件流的数据集(例如作为来自网站的跟踪事件触发)。所有事件都有一个时间戳。我们经常遇到的一个用例是试图找到给定字段的第一个非空值。例如,像这样的事情让我们最接近那里:

val eventsDf = spark.read.json(jsonEventsPath) 

case class ProjectedFields(visitId: String, userId: Int, timestamp: Long ... )

val projectedEventsDs = eventsDf.select(
eventsDf("message.visit.id").alias("visitId"),
eventsDf("message.property.user_id").alias("userId"),
eventsDf("message.property.timestamp"),

...

).as[ProjectedFields]

projectedEventsDs.groupBy($"visitId").agg(first($"userId", true))

上面代码的问题在于输入到 first 的数据的顺序。不保证聚合功能。我希望它按 timestamp 排序以确保它是时间戳的第一个非空用户 ID,而不是任何随机的非空用户 ID。

有没有办法定义分组内的排序?

使用 Spark 2.10

顺便说一句,在 SPARK DataFrame: select the first row of each group 中为 Spark 2.10 建议的方式是在分组之前进行排序——这是行不通的。例如下面的代码:
case class OrderedKeyValue(key: String, value: String, ordering: Int)
val ds = Seq(
OrderedKeyValue("a", null, 1),
OrderedKeyValue("a", null, 2),
OrderedKeyValue("a", "x", 3),
OrderedKeyValue("a", "y", 4),
OrderedKeyValue("a", null, 5)
).toDS()

ds.orderBy("ordering").groupBy("key").agg(first("value", true)).collect()

有时会返回 Array([a,y])有时 Array([a,x])

最佳答案

使用我心爱的 window (......体验你的生活变得多么简单!)

import org.apache.spark.sql.expressions.Window
val byKeyOrderByOrdering = Window
.partitionBy("key")
.orderBy("ordering")
.rangeBetween(Window.unboundedPreceding, Window.unboundedFollowing)

import org.apache.spark.sql.functions.first
val firsts = ds.withColumn("first",
first("value", ignoreNulls = true) over byKeyOrderByOrdering)

scala> firsts.show
+---+-----+--------+-----+
|key|value|ordering|first|
+---+-----+--------+-----+
| a| null| 1| x|
| a| null| 2| x|
| a| x| 3| x|
| a| y| 4| x|
| a| null| 5| x|
+---+-----+--------+-----+

注意:不知何故,Spark 2.2.0-SNAPSHOT(今天构建)无法给我正确的答案,没有 rangeBetween我认为应该是默认的无界范围。

关于apache-spark - 如何在组中找到第一个非空值? (使用数据集api进行二次排序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42986965/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com