apache-spark - SparkSql if value null 取前一个
问题描述
所以我有这个数据框
+---+-------------+-----+
| id| timestamp| num|
+---+-------------+-----+
| 10|1546300799000| 37.5|
| 10|1546300800000| null|
| 10|1546300801000| null|
| 10|1546300802000|37.51|
| 20|1546300804000| null|
| 10|1546300806000| 37.5|
| 10|1546300807000| null|
+---+-------------+-----+
我想要实现的是,num
如果存在,则必须使用值本身更新,或者如果为 null,则从前一行获取的“最后一个”值(按时间戳排序并按 id 分组)
所以这应该是输出
+---+-------------+-----+
| id| timestamp| num|
+---+-------------+-----+
| 10|1546300799000| 37.5|
| 10|1546300800000| 37.5|
| 10|1546300801000| 37.5|
| 10|1546300802000|37.51|
| 20|1546300804000| null|
| 10|1546300806000| 37.5|
| 10|1546300807000| 37.5|
+---+-------------+-----+
我想出了这个解决方案
w = Window.partitionBy('id').orderBy('timestamp')
final = joined.withColumn('num2', when(col('num').isNull(), lag(col('num')).over(w)).otherwise(col('num')))
但这是我得到的输出
+---+-------------+-----+-----+
| id| timestamp| num| num2|
+---+-------------+-----+-----+
| 10|1546300799000| 37.5| 37.5|
| 10|1546300800000| null| 37.5|
| 10|1546300801000| null| null|
| 10|1546300802000|37.51|37.51|
| 20|1546300804000| null| null|
| 10|1546300806000| 37.5| 37.5|
| 10|1546300807000| null| 37.5|
+---+-------------+-----+-----+
如您所见,如果isNull,值将获取前一个值,但是如果您查看第三行,我会得到一个空值,并且我假设因为它获取了第二行的值,但是当它仍未更新时(所以仍然是原始数据帧中的空值)。
我有点迷茫我应该如何进行。有什么帮助吗?
解决方案
您正在期待填写一项措施,不幸的是,Pyspark 不像 Pandas 那样内置。但是有一个解决方法。
from pyspark.sql import functions as F
from pyspark.sql.window import Window
window = Window.partitionBy('id')\
.orderBy('timestamp')\
.rowsBetween(Window.unboundedPreceding, Window.currentRow)
final = joined.\
withColumn('numFilled', F.last('num',ignorenulls = True).over(window)
所以这样做是它根据分区键和顺序列构造您的窗口。它还告诉窗口回顾以前的行和当前行。最后,在每一行,您返回最后一个不为空的值(根据您的窗口记住,这包括您的当前行)
推荐阅读
- java - HashMap 类型
- , 列表
> 不接受 - , 列表
> - flutter - 如何在 navigator.pop 中定义路由
- c++ - 有效检查两个浮点值是否具有不同的符号
- php - 使用 Laravel 护照和 Vuejs。Auth::User() 在刀片上不起作用
- android - Android Studio 布局设计消失了
- javascript - 如何使用别名从 ExtJS 中的商店引用模型?
- gnuplot - 如何在gnuplot的多个图中设置背景颜色?
- jira - 使用 API 获取已删除的 JIRA 问题列表
- c++ - 由多个分隔符分割 C++
- flutter - Flutter - 网格视图,如果所有项目都在屏幕上可见,则停止滚动