PySpark DataFrame嵌套行过滤:筛选指定条件数据的方法
解决PySpark嵌套数组的对应位置筛选问题
问题分析
你的DataFrame中Names是三层嵌套数组,Status是一维数组,需要找到**Names中某位置的姓名包含"mert",且对应索引的Status为Active**的行。核心是将嵌套的Names展开到与Status对应的层级,再通过拉链(zip)关联对应位置的状态,最后筛选符合条件的行。
解决方案代码
from pyspark.sql import functions as F # 1. 提取Names第二层数组(原Names是三层数组,最外层仅一个元素) df = df.withColumn("name_pairs", F.element_at("Names", 1)) # 2. 将姓名对数组与Status数组拉链,让每个姓名对对应一个状态 df = df.withColumn("zipped_pairs", F.array_zip("name_pairs", "Status")) # 3. 定义筛选条件:存在至少一组符合要求的姓名-状态对 filter_condition = F.exists( "zipped_pairs", lambda pair: F.trim(pair.name_pairs[1]).contains("mert") & (pair.Status == "Active") ) # 4. 筛选并保留原列 filtered_df = df.filter(filter_condition).select("ID", "Names", "Status") # 查看结果 filtered_df.show(truncate=False)
代码说明
- 提取姓名对数组:用
element_at取出Names最外层数组的唯一元素,得到与Status长度匹配的姓名对数组(如[[aaaa, mert], [cccc, Doe]])。 - 拉链关联:
array_zip将姓名对数组和Status数组按索引配对,生成结构体数组(每个元素包含一组姓名对和对应状态)。 - 条件判断:
exists函数检查是否存在满足条件的配对:姓名对的第二个元素(名字)包含"mert"(trim处理空格),且对应状态为Active。 - 筛选结果:应用条件筛选后,保留原DataFrame的列。
若需展开显示单个符合条件的配对
如果需要查看具体哪一组姓名-状态对符合要求,可在拉链后展开数组再筛选:
# 展开拉链后的数组 expanded_df = df.withColumn("pair", F.explode("zipped_pairs")) # 筛选符合条件的单个配对 expanded_filtered = expanded_df.filter( F.trim(F.col("pair.name_pairs")[1]).contains("mert") & (F.col("pair.Status") == "Active") ).select("ID", "pair.name_pairs", "pair.Status") expanded_filtered.show(truncate=False)
内容的提问来源于stack exchange,提问作者veganzombie
相关产品推荐
相关产品推荐

