首页 > 解决方案 > Pyspark 从空数据框中选择抛出异常

问题描述

这个问题与这个问题类似,但没有答案,我有一个数据框,如果存在,我会从中选择数据

schema = StructType([
    StructField("file_name", StringType(), True),
    StructField("result", ArrayType(StructType()), True),

])

df = rdd.toDF(schema=schema)

print((df.count(), len(df.columns))) # 0,2

df.cache()

df = df.withColumn('result', F.explode(df['result']))

get_doc_id = F.udf(lambda line: ntpath.basename(line).replace('_all.txt', ''), StringType())

df = df.filter(df.result.isNotNull()).select(F.lit(job_id).alias('job_id'),
                                             get_doc_id(df['file_name']).alias('doc_id'),
                                             df['result._2'].alias('line_content'),
                                             df['result._4'].alias('line1'),
                                             df['result._3'].alias('line2'))

当数据框为空时,上面会引发错误

pyspark.sql.utils.AnalysisException: 'No such struct field _2 in ;

它不应该只在result列有数据时执行吗?以及如何克服这一点?

标签: apache-sparkpyspark

解决方案


Spark 懒惰地执行代码。因此它不会检查您的过滤条件中是否有数据。您的代码在分析阶段失败,因为您的数据中没有名为 result._2 的列。您在结果列的架构中传递空的 StructType 。您应该将其更新为如下内容:


schema = StructType([
    StructField("file_name", StringType(), True),
    StructField("result", ArrayType(StructType([StructField("line_content",StringType(),True), StructField("line1",StringType(),True), StructField("line2",StringType(),True)])), True)
])


df = spark.createDataFrame(sc.emptyRDD(),schema=schema)

df = df.withColumn('result', F.explode(df['result']))

get_doc_id = F.udf(lambda line: ntpath.basename(line).replace('_all.txt', ''), StringType())


df = df.filter(df.result.isNotNull()).select(F.lit('job_id').alias('job_id'),
                                             get_doc_id(df['file_name']).alias('doc_id'),
                                             df['result.line_content'].alias('line_content'),
                                             df['result.line1'].alias('line1'),
                                             df['result.line2'].alias('line2'))

推荐阅读