pyspark - 在除前两列之外的每列上前向填充具有最新非空值的空值
问题描述
我有一个数据框,在我的数据透视之后它创建了带有空值的行。我需要用最新的非空值替换空值。我需要对 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 列之外,我如何再次遍历所有这些。
解决方案
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|
# +--------+-----+-----+------+
推荐阅读
- sql - 有没有办法从多个表中选择此名称?
- sql - 从字符串转换日期和/或时间并从日期中提取季度/年时转换失败
- java - 错误 - Assert 类型中的方法 assertEquals(Object, object) 不适用于参数 (String, Void)
- excel - 在数据透视表中重复标签但添加唯一标识符
- android - 如何确定是否已经设置了 FLAG_KEEP_SCREEN_ON?
- c++ - 有没有办法保存用户输入的文本?
- flutter - Flutter bloc监听器中的延迟状态检查
- excel - 我可以使用 CSV 文件作为 Excel 数据透视数据源吗?
- flutter - 如何使 Flutter 应用程序字体大小独立于设备设置?
- c++ - C++ C4244 =':从 'std::streamsize' 转换为 'unsigned short',可能会丢失数据;任何解决方案?