Apache spark 选择数据框中不存在的列
因此,我从一个XML文件创建了一个Apache spark 选择数据框中不存在的列,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,因此,我从一个XML文件创建了一个dataframe。它有一些关于经销商的信息,然后经销商有多辆车-每辆车都是cars元素的子元素,由value元素表示-每辆cars.value元素都有不同的车属性。因此,我使用explode函数为经销商的每辆车创建一行,如下所示: exploded\u dealer=df.select('dealer\u id',exploded('cars.value')。别名('a\u car')) 现在我想获得汽车的各种属性。value 我是这样做的: car\u d
dataframe
。它有一些关于经销商的信息,然后经销商有多辆车-每辆车都是cars
元素的子元素,由value
元素表示-每辆cars.value
元素都有不同的车属性。因此,我使用explode
函数为经销商的每辆车创建一行,如下所示:
exploded\u dealer=df.select('dealer\u id',exploded('cars.value')。别名('a\u car'))
现在我想获得汽车的各种属性。value
我是这样做的:
car\u details\u df=分解的经销商。选择('dealer\u id'、'a\u car.attribute1'、'a\u car.attribute2')
这很好。但是有时候cars.value
元素没有我在查询中指定的所有属性。例如,一些cars.value
元素可能只有attribute1-然后在运行上述代码时,我将得到以下错误:
pyspark.sql.utils.AnalysisException:u“无法解析'attribute2'
给定输入列:[经销商id,属性1];”
我如何要求Spark执行相同的查询。但是如果属性2不存在,只需返回None
更新我读取的数据如下:
initial_file_df=sqlContext.read.format('com.databricks.spark.xml')。选项(rowTag='dealer')。加载(“”)
分解经销商=df.select('financial_data',分解('cars.value')。别名('a_car'))
既然您已经对模式做出了特定的假设,那么最好的办法就是使用可空
可选字段显式定义它,并在导入数据时使用它
假设您希望文档类似于:
<rows>
<row>
<id>1</id>
<objects>
<object>
<attribute1>...</attribute1>
...
<attributebN>...</attributeN>
</object>
</objects>
</row>
</rows>
您可以将架构定义为:
schema = StructType([
StructField("objects", StructType([
StructField("object", StructType([
StructField("attribute1", StringType(), True),
StructField("attribute2", LongType(), True)
]), True)
]), True),
StructField("id", LongType(), True)
])
并与reader一起使用:
spark.read.schema(schema).option("rowTag", "row").format("xml").load(...)
它对属性的任何子集都有效({∅, {attribute1},{attribute2},{attribute1,attribute2})。同时比依赖模式推断更有效。这很棘手,因为失败的是SQL查询,而不是python代码。让我惊讶的是,通常一个数据帧有一个模式,这个模式可以包含属性,也可以不包含属性。所以要么它是一个bug,要么你做了一些棘手的事情来构建你的数据集。如果是,请具体说明。无论如何,有趣的是,我认为在sparksql中没有类似的TRY。这意味着您必须使用一种变通方法,比如在创建数据帧时强制使用具有所有属性的模式。“让我惊讶的是,通常一个数据帧只有一个模式”-所以问题是:我的代码是静态的,所以我可以指定始终从文件中获取列a、b、c,因为我知道他们在那里,我只需要那三列。但有一天可能会有一个包含a、b、d列的xml—但我仍然只需要a、b、c列,即使这意味着我没有获得c列的数据。因为我的代码是静态的,它会要求a、b、c,而且因为c缺失,它会失败。@Dennis我知道这不是你问题的答案,但它可能会有所帮助:你可以先做一个逻辑,得到模式,然后相应地生成查询。
spark.read.schema(schema).option("rowTag", "row").format("xml").load(...)