Spark:如果数据框中不存在列,则返回空列

pal*_*upz 6 apache-spark apache-spark-sql pyspark pyspark-sql

如下面的代码所示,我正在将一个 JSON 文件读入一个数据帧,然后从该数据帧中选择一些字段到另一个字段中。

df_record = spark.read.json("path/to/file.JSON",multiLine=True)

df_basicInfo = df_record.select(col("key1").alias("ID"), \
                                col("key2").alias("Status"), \
                                col("key3.ResponseType").alias("ResponseType"), \
                                col("key3.someIndicator").alias("SomeIndicator") \
                                )
Run Code Online (Sandbox Code Playgroud)

问题是,有时,JSON 文件没有我尝试获取的某些键,例如ResponseType. 所以它最终会抛出如下错误:

org.apache.spark.sql.AnalysisException: No such struct field ResponseType
Run Code Online (Sandbox Code Playgroud)

如何在不强制使用模式的情况下解决此问题?当它不可用时,是否可以使其在该列下返回 NULL?

我如何检测 spark 数据帧是否有列确实提到了如何检测数据帧中的列是否可用。然而,这个问题是关于如何使用该功能。

小智 8

使用has_column功能定义在这里通过zero323一般准则有关添加空列要么

from pyspark.sql.functions import lit, col, when
from pyspark.sql.types import *

if has_column(df_record, "key3.ResponseType"):
    df_basicInfo = df_record.withColumn("ResponseType", col("key3.ResponseType"))
else:
    # Adjust types according to your needs
    df_basicInfo = df_record.withColumn("ResponseType", lit(None).cast("string")) 
Run Code Online (Sandbox Code Playgroud)

并为您需要的每一列重复,或

df_record.withColumn(
   "ResponseType", 
   when(
       lit(has_column(df_record, "key3.ResponseType")),
       col("key3.ResponseType")
   ).otherwise(lit(None).cast("string"))
Run Code Online (Sandbox Code Playgroud)

根据您的要求调整类型,并对剩余的列重复此过程。

或者定义一个涵盖所有所需类型的模式:

schema = StructType([
    StructField("key1", StringType()),
    StructField("key2", StringType()),
    StructField("key2", StructType([
        StructField("ResponseType", StringType()),
        StructField("someIndicator", StringType()),
    ]))
])

df_record = spark.read.schema(schema).json("path/to/file.JSON",multiLine=True)
Run Code Online (Sandbox Code Playgroud)

(再次调整类型),并使用您当前的代码。

  • SparkSQL 有版本吗? (3认同)
  • 如果没有列,则否则失败。 (3认同)
  • 我尝试了这个,但它总是评估 `col("key3.ResponseType")` 并且如果该列不存在,它将抛出错误。 (3认同)