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窗口函数实现序列化缺失值前向填充的具体步骤和示例代码。

VisualizeAI
VisualizeAI

用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语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

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

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

436

2024.03.01

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

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

970

2023.11.02

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

37

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

52

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

8

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

热门下载

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

精品课程

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

共32课时 | 3.8万人学习

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号