0

0

PySpark数据框:高效实现序列化缺失值前向填充

花韻仙語

花韻仙語

发布时间:2025-09-06 11:49:03

|

169人浏览过

|

来源于php中文网

原创

PySpark数据框:高效实现序列化缺失值前向填充

本文详细介绍了如何在PySpark DataFrame中高效地实现基于序列的前向填充缺失值。针对group_id等列中出现的空值,通过利用PySpark的窗口函数(Window.orderBy和F.last),能够根据row_id的顺序,将前一个非空值填充到后续的空值位置,确保数据的完整性和逻辑连贯性,尤其适用于大规模数据集的处理。

引言

在数据处理过程中,我们经常会遇到数据框中存在缺失值的情况。特别是在某些场景下,缺失值的填充需要遵循特定的逻辑,例如根据序列顺序,将前一个非空值填充到后续的空值位置。本文将聚焦于pyspark dataframe,提供一种高效且专业的方法来解决这类序列化缺失值前向填充问题。例如,当group_id列中存在空值,而我们希望根据row_id的递增顺序,用最近的非空group_id来填充后续的空值,直到遇到下一个非空group_id为止。

核心概念:PySpark窗口函数

PySpark的窗口函数(Window Functions)是处理此类序列化操作的强大工具。它们允许我们在数据框的特定“窗口”内执行计算,而这个窗口可以根据一行或多行的顺序和分区来定义。

对于序列化前向填充,我们需要定义一个窗口,该窗口包含当前行以及其之前的所有行。然后,在这个窗口内找到group_id的最后一个非空值。

关键的窗口函数组件包括:

  • Window.orderBy("row_id"): 定义窗口的排序规则,确保我们按照row_id的顺序进行处理。
  • rowsBetween(Window.unboundedPreceding, 0): 定义窗口的范围。
    • Window.unboundedPreceding: 表示窗口从分区的第一行开始。
    • 0: 表示窗口的结束点是当前行(偏移量为0)。 结合起来,这个窗口定义了从数据开始到当前行(包括当前行)的所有记录。
  • F.last("column_name", ignorenulls=True): 在定义的窗口内,获取指定列的最后一个非空值。ignorenulls=True参数至关重要,它确保我们只考虑非空值。

实现步骤与示例代码

下面是使用PySpark窗口函数实现序列化缺失值前向填充的具体步骤和示例代码。

WowTo
WowTo

用AI建立视频知识库

下载
  1. 初始化Spark会话: 首先,需要创建一个SparkSession。
  2. 创建示例DataFrame: 根据问题描述,创建一个包含row_id和group_id的DataFrame,其中group_id包含空值。
  3. 定义窗口规范: 使用Window.orderBy和rowsBetween定义窗口。
  4. 应用last函数填充缺失值: 使用F.last函数结合ignorenulls=True,在定义的窗口上应用填充逻辑。
from pyspark.sql import SparkSession
from pyspark.sql import functions as F
from pyspark.sql.window import Window

# 1. 创建Spark会话
spark = SparkSession.builder.appName("SequentialFillNulls").getOrCreate()

# 2. 创建示例DataFrame
data = [
    (1, 1), (2, None), (3, None), (4, None),
    (5, 5), (6, None), (7, None),
    (8, 8), (9, None), (10, None), (11, None), (12, None)
]
columns = ["row_id", "group_id"]
df = spark.createDataFrame(data, columns)

print("原始DataFrame:")
df.show()

# 3. 定义窗口规范
# 窗口按row_id排序,范围从分区开始到当前行
windowSpec = Window.orderBy("row_id").rowsBetween(Window.unboundedPreceding, 0)

# 4. 应用last函数填充缺失值
# 使用last函数获取窗口内最后一个非空group_id
filled_df = df.withColumn(
    "group_id",
    F.last("group_id", ignorenulls=True).over(windowSpec)
)

print("填充缺失值后的DataFrame:")
filled_df.show()

# 关闭Spark会话
spark.stop()

运行上述代码,将得到以下输出:

原始DataFrame:
+------+--------+
|row_id|group_id|
+------+--------+
|     1|       1|
|     2|    null|
|     3|    null|
|     4|    null|
|     5|       5|
|     6|    null|
|     7|    null|
|     8|       8|
|     9|    null|
|    10|    null|
|    11|    null|
|    12|    null|
+------+--------+

填充缺失值后的DataFrame:
+------+--------+
|row_id|group_id|
+------+--------+
|     1|       1|
|     2|       1|
|     3|       1|
|     4|       1|
|     5|       5|
|     6|       5|
|     7|       5|
|     8|       8|
|     9|       8|
|    10|       8|
|    11|       8|
|    12|       8|
+------+--------+

关键点与注意事项

  • row_id的唯一性和顺序性: 本方案的核心在于row_id能够提供一个明确的排序基准。确保row_id是唯一且递增的,对于正确实现前向填充至关重要。如果原始数据没有这样的列,可能需要先通过zipWithIndex或monotonically_increasing_id等方法创建一个。
  • ignorenulls=True的重要性: 在F.last函数中,ignorenulls=True参数确保了只有非空值才会被考虑为“最后一个值”。如果没有这个参数,last函数可能会返回窗口中的最后一个值,即使它是null,从而导致填充不正确。
  • 性能考量: 窗口函数在PySpark中是高度优化的,可以高效处理大规模数据集。然而,Window.orderBy操作涉及到数据的全局排序,可能会在集群中引起数据混洗(shuffle),对于超大规模数据集,这可能是性能瓶颈之一。在实际应用中,应评估其对性能的影响。
  • 分区(Partitioning): 如果数据本身可以逻辑地划分为多个独立的组(例如,除了row_id还有一个category_id),并且需要在每个category_id内部进行独立的前向填充,那么可以在窗口规范中添加partitionBy("category_id")。例如:Window.partitionBy("category_id").orderBy("row_id").rowsBetween(Window.unboundedPreceding, 0)。
  • 替代方法对比: 对于简单的非序列化缺失值填充,PySpark提供了df.fillna()方法。但fillna()无法实现基于前一个值的序列化填充逻辑,因此窗口函数是此类问题的首选方案。

总结

通过PySpark的窗口函数,我们可以优雅且高效地解决DataFrame中基于序列的前向填充缺失值问题。Window.orderBy结合rowsBetween定义了灵活的窗口范围,而F.last(..., ignorenulls=True)则精确地提取了所需的非空值进行填充。这种方法不仅适用于小规模数据,更能在处理百万级甚至亿级行的大规模数据集时展现其强大的性能和可靠性。掌握这一技术,将极大地提升PySpark数据处理的效率和准确性。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

973

2023.11.02

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

6

2026.01.20

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

59

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

80

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

38

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号