apache-spark - 使用火花窗口函数获取最后一个值
问题描述
假设我有一个这样的数据框。
val df = sc.parallelize(Seq(
(1.0, 1,"Matt"),
(1.0, 2,"John"),
(1.0, 3,null.asInstanceOf[String]),
(-1.0, 2,"Adam"),
(-1.0, 4,"Steve"))
).toDF("id", "timestamp","name")
我想获取按时间戳排序的每个 id 的最后一个非空值。这是我的窗户
val partitionWindow = Window.partitionBy($"id").orderBy($"timestamp".desc)
我正在创建一个独特的窗口数据
val filteredDF = df.filter($"name".isNotNull).withColumn("firstName", first("name") over (partitionWindow)).drop("timestamp","name").distinct
并将其连接回实际数据
val joinedDF = df.join(filteredDF, windowDF.col("id") === filteredDF.col("id")).drop(filteredDF.col("id"))
joinedDF.show()
它工作正常,但我不喜欢这个解决方案,任何人都可以建议我更好的东西吗?
另外,谁能告诉我为什么最后一个功能不起作用?我试过了,结果不正确
val partitionWindow = Window.partitionBy($"id").orderBy($"timestamp")
val windowDF = df.withColumn("lastName", last("name") over (partitionWindow))
解决方案
如果您想传播最后一个已知值(它与使用的逻辑不同join
),您应该:
ORDER BY timestamp
.- 忽略:
last
_nulls
val partitionWindow = Window.partitionBy($"id").orderBy($"timestamp")
df.withColumn("lastName", last("name", true) over (partitionWindow)).show
// +----+---------+-----+--------+
// | id|timestamp| name|lastName|
// +----+---------+-----+--------+
// |-1.0| 2| Adam| Adam|
// |-1.0| 4|Steve| Steve|
// | 1.0| 1| Matt| Matt|
// | 1.0| 2| John| John|
// | 1.0| 3| null| John|
// +----+---------+-----+--------+
如果要全局获取最后一个值:
ORDER BY timestamp
.- 设置无界框架。
- 忽略:
last
_nulls
val partitionWindow = Window.partitionBy($"id").orderBy($"timestamp")
.rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
df.withColumn("lastName", last("name", true) over (partitionWindow)).show
// +----+---------+-----+--------+
// | id|timestamp| name|lastName|
// +----+---------+-----+--------+
// |-1.0| 2| Adam| Steve|
// |-1.0| 4|Steve| Steve|
// | 1.0| 1| Matt| John|
// | 1.0| 2| John| John|
// | 1.0| 3| null| John|
// +----+---------+-----+--------+
推荐阅读
- c# - 模拟服务和网络位置的问题
- css - 无法将 css 应用于 React className
- ios - 在自定义过渡期间使用 .scaleAspectFill 内容模式为图像视图的比例设置动画
- javascript - 如何检查鼠标光标是否超过某个 x 坐标?
- python - 为什么从 IronPython 调用 Python 时命令窗口会闪烁打开和关闭?
- vim - Neovim scp 不提示输入密码
- git - Git fetch 或 Git pull 来更新 Web 服务器上的文件?
- javascript - 如何从javascript中的API字符串中确定多个不同大小的子字符串
- javascript - 使用 Javascript 计算小时和分钟的差异并将结果填充到另一个字段中
- perl - perl 函数定义因未初始化值而失败