在除前两列之外的每列上前向填充具有最新非空值的空值

Posted

技术标签:

【中文标题】在除前两列之外的每列上前向填充具有最新非空值的空值【英文标题】:forward fill nulls with latest non null value over each column except first two 【发布时间】:2021-08-10 00:15:50 【问题描述】:

我有一个数据框,在我进行数据透视后,它创建了具有空值的行。我需要用最新的非空值替换空值。除了前两列之外,我需要对 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 列之外,我如何再次遍历所有这些。

【问题讨论】:

【参考方案1】:

使用last 函数并将ignorenulls 设置为True 以获取窗口内的最后一个非空值(如果全部为空则返回空)。要遍历除前两列之外的所有列,您可以使用列表推导。

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|
# +--------+-----+-----+------+

【讨论】:

它是否也自动填充按日期列排序? 上面的代码使用您在问题中定义的ffill 窗口,所以是的

以上是关于在除前两列之外的每列上前向填充具有最新非空值的空值的主要内容,如果未能解决你的问题,请参考以下文章

数据库怎么用非空值填充为空值?

SQL将多行中的字段的空值填充为先前的非空值

用 pentaho 计算每列空值的数量

查找 2 列的空值的过程,如果为真,则使用这些行中的一些值来执行某些操作

如何在熊猫数据框中仅填充选定列的空值? [复制]

分组日期滚动中最新非空值的 Pandas 日期索引