首页 > 解决方案 > 在除前两列之外的每列上前向填充具有最新非空值的空值

问题描述

我有一个数据框,在我的数据透视之后它创建了带有空值的行。我需要用最新的非空值替换空值。我需要对 df 中的每一列执行此操作,除了前两列

样本:

columns = ['date', 'group', 'value', 'value2']
data = [\
        ('2020-1-1','b', 5, 20),\
        ('2020-2-1','a', None, 15),\
        ('2020-3-1','a', 20, None),\
        ('2020-3-1','b', 10, None),\
        ('2020-2-1','b', None, None),\
        ('2020-1-1','a', None, None),\
        ('2020-4-1','b', None, 100)]
sdf = spark.createDataFrame(data, columns)

填充逻辑的窗口函数

# fill nulls with previous non null value
plist = ['group']
ffill = Window.partitionBy(*plist).orderBy('date').rowsBetween(Window.unboundedPreceding, Window.currentRow)

目标:我基本上想通过替换空值来覆盖 value 和 value2 列。这是一个示例,但我的实际 df 有超过 30 列。除了第 1 列和第 2 列之外,我如何再次遍历所有这些。

标签: pysparkapache-spark-sql

解决方案


Use last function with ignorenulls set to True to get the last non-null value within a window (if all null then return null). For looping through all columns except the first two, you can use list comprehension.

from pyspark.sql.functions import col, last

# all colums except the first two
cols = sdf.columns[2:]

sdf = sdf.select('date', 'group', 
                 *[last(col(c), ignorenulls=True).over(ffill).alias(c) for c in cols])
sdf.show()

# +--------+-----+-----+------+
# |    date|group|value|value2|
# +--------+-----+-----+------+
# |2020-1-1|    b|    5|    20|
# |2020-2-1|    b|    5|    20|
# |2020-3-1|    b|   10|    20|
# |2020-4-1|    b|   10|   100|
# |2020-1-1|    a| null|  null|
# |2020-2-1|    a| null|    15|
# |2020-3-1|    a|   20|    15|
# +--------+-----+-----+------+

推荐阅读