pyspark中dataframe缺失值填充

在工作中我们经常面对各种缺失值的处理,当使用pandas,缺失值可以使用fillna,指定method=ffill或bfill就能实现
缺失值的前向或后向填充。但是在spark应用中,需要稍微做一些改变。比如说我们先创建一个DataFrame:

df = spark.createDataFrame(
	[("a", 1, '2019-06-15 13:20'),
	("a",2, None),("a",3, None),
	("a",4, '2019-06-15 13:40'),
	("a",5, '2019-06-15 14:40'),
	("a",6, None),
	("b",1, '2019-06-15 13:42'),
	("b",2, None),
	("b",3, None)], 
	["id","num", "time"]
)
df.show()
+---+---+----------------+
| id|num|            time|
+---+---+----------------+
|  a|  1|2019-06-15 13:20|
|  a|  2|            null|
|  a|  3|            null|
|  a|  4|2019-06-15 13:40|
|  a|  5|2019-06-15 14:40|
|  a|  6|            null|
|  b|  1|2019-06-15 13:42|
|  b|  2|            null|
|  b|  3|            null|
+---+---+----------------+

假如有这样的场景:对于不同的用户"a"和"b",它有一个维度num,还有一个时间列。但是time列存在很多缺失值,现在想要填充这些null值,要求是向前填,
也就是说如果当前有值不作处理,若为空值,就向前找离他最近的值填充。

要实现这个功能就要借助spark的windows函数,代码如下:

from pyspark.sql import Window
from pyspark.sql.functions import last
import sys

# 开窗函数,以id做分组,指定排序方式,设置窗口大小
window = Window.partitionBy("id").orderBy("num").rowsBetween(-sys.maxsize, 0)
# last函数,返回分组中的最后一个值。ignorenulls为True表示只对null值应用
filled = last(df["time"], ignorenulls=True).over(window)
spark_df = df.withColumn("tmp_time", filled)

spark_df.orderBy("id", "num").show().show()

结果如下:

+---+---+----------------+----------------+
| id|num|            time|        tmp_time|
+---+---+----------------+----------------+
|  a|  1|2019-06-15 13:20|2019-06-15 13:20|
|  a|  2|            null|2019-06-15 13:20|
|  a|  3|            null|2019-06-15 13:20|
|  a|  4|2019-06-15 13:40|2019-06-15 13:40|
|  a|  5|2019-06-15 14:40|2019-06-15 14:40|
|  a|  6|            null|2019-06-15 14:40|
|  b|  1|2019-06-15 13:42|2019-06-15 13:42|
|  b|  2|            null|2019-06-15 13:42|
|  b|  3|            null|2019-06-15 13:42|
+---+---+----------------+----------------+

可以发现确实实现了这个功能。

原文参考这个博客,有兴趣可以了解下
https://johnpaton.net/posts/forward-fill-spark/

你可能感兴趣的:(大数据,spark,dataframe)