PySpark移除DataFrame首行报错AttributeError: _jdf求助
解决PySpark中使用subtract移除首行时的AttributeError问题
首先得把报错原因说清楚:你用avg_calc.first()拿到的是一个Row对象,但DataFrame.subtract()方法要求传入的必须是另一个DataFrame,不是单个Row。Row对象根本没有_jdf这个属性(这是DataFrame底层的Java对象引用),所以才会抛出AttributeError: _jdf。
下面给你几个实用的解决方案,按需选择就行:
方案一:删除物理第一行数据(不管内容)
如果只是想删掉DataFrame里的物理第一行,推荐用行号过滤的方式:
from pyspark.sql.window import Window from pyspark.sql.functions import row_number, lit # 创建全局窗口生成连续行号(小数据量适用,大数据量建议加分区键优化) window_spec = Window.orderBy(lit(1)) # 给数据添加行号列 avg_calc_with_row = avg_calc.withColumn("row_num", row_number().over(window_spec)) # 过滤掉行号为1的第一行,再删除辅助列 no_header = avg_calc_with_row.filter(avg_calc_with_row.row_num > 1).drop("row_num") no_header.show()
如果是大数据量,用monotonically_increasing_id()更高效(虽然不是严格连续,但能保证唯一递增):
from pyspark.sql.functions import monotonically_increasing_id, min # 添加唯一递增ID列 avg_calc_with_id = avg_calc.withColumn("id", monotonically_increasing_id()) # 获取第一行的ID值 min_id = avg_calc_with_id.select(min("id")).first()[0] # 过滤掉该行并删除辅助列 no_header = avg_calc_with_id.filter(avg_calc_with_id.id != min_id).drop("id") no_header.show()
方案二:删除所有与首行内容一致的记录
如果你的需求是删掉所有和首行内容完全匹配的行(不止物理第一行),可以把首行转成临时DataFrame再用subtract:
# 将首行Row对象转换成同结构的DataFrame header_df = spark.createDataFrame([avg_calc.first()], schema=avg_calc.schema) # 现在可以正常调用subtract了 no_header = avg_calc.subtract(header_df) no_header.show()
⚠️ 注意:这个方法会删除所有和首行内容完全重复的行,如果你有合法的重复数据,会被误删,谨慎使用。
方案三:读取文件时直接跳过首行数据
如果你的CSV里,表头之后的第一行是无效数据,其实可以在读取阶段就处理:
# Spark 2.4+支持skipLines参数,直接跳过指定行数 avg_calc = spark.read.csv("quiz2_algo.csv", header=True, inferSchema=True, skipLines=1)
这里的skipLines=1会先跳过文件的第一行?不对——因为已经设置了header=True,它会先跳过skipLines行,再把下一行作为表头。比如原文件结构是:
col1,col2 val1,val2 val3,val4
想跳过val1,val2这行,就用skipLines=1,读取时会把第一行当表头,跳过第二行,从第三行开始加载数据。
内容的提问来源于stack exchange,提问作者Unix
相关产品推荐
相关产品推荐

