只能对具有兼容列类型 Spark 数据框的表执行联合
Posted
技术标签:
【中文标题】只能对具有兼容列类型 Spark 数据框的表执行联合【英文标题】:Union can only be performed on tables with the compatible column types Spark dataframe 【发布时间】:2017-11-28 05:03:22 【问题描述】:这是我的联合代码:
val dfToSave=dfMainOutput.union(insertdf.select(dfMainOutput).withColumn("FFAction", when($"FFAction" === "O" || $"FFAction" === "I", lit("I|!|")))
当我进行联合时,出现以下错误:
org.apache.spark.sql.AnalysisException: Union can only be performed on tables with the compatible column types. string <> boolean at the 11th column of the second table;;
'Union
这是两个数据框的架构:
insertdf.printSchema()
root
|-- OrganizationID: long (nullable = true)
|-- SourceID: integer (nullable = true)
|-- AuditorID: integer (nullable = true)
|-- AuditorOpinionCode: string (nullable = true)
|-- AuditorOpinionOnInternalControlCode: string (nullable = true)
|-- AuditorOpinionOnGoingConcernCode: string (nullable = true)
|-- IsPlayingAuditorRole: boolean (nullable = true)
|-- IsPlayingTaxAdvisorRole: boolean (nullable = true)
|-- AuditorEnumerationId: integer (nullable = true)
|-- AuditorOpinionId: integer (nullable = true)
|-- AuditorOpinionOnInternalControlsId: string (nullable = true)
|-- AuditorOpinionOnGoingConcernId: string (nullable = true)
|-- IsPlayingCSRAuditorRole: boolean (nullable = true)
|-- FFAction: string (nullable = true)
|-- DataPartition: string (nullable = true)
这是第二个数据框的架构:
dfMainOutput.printSchema()
root
|-- OrganizationID: long (nullable = true)
|-- SourceID: integer (nullable = true)
|-- AuditorID: integer (nullable = true)
|-- AuditorOpinionCode: string (nullable = true)
|-- AuditorOpinionOnInternalControlCode: string (nullable = true)
|-- AuditorOpinionOnGoingConcernCode: string (nullable = true)
|-- IsPlayingAuditorRole: boolean (nullable = true)
|-- IsPlayingTaxAdvisorRole: boolean (nullable = true)
|-- AuditorEnumerationId: integer (nullable = true)
|-- AuditorOpinionId: integer (nullable = true)
|-- AuditorOpinionOnInternalControlsId: integer (nullable = true)
|-- AuditorOpinionOnGoingConcernId: boolean (nullable = true)
|-- IsPlayingCSRAuditorRole: string (nullable = true)
|-- FFAction: string (nullable = true)
|-- DataPartition: string (nullable = true)
为了避免这个问题,我可能必须为每一列写一个select
。
那么是否有任何 Scala 语法可以管理种姓类型或将两个数据帧设为相同类型?
这是我迄今为止尝试过的,但仍然遇到同样的错误:
val columns = dfMainOutput.columns.toSet.intersect(insertdf.columns.toSet).map(col).toSeq
//Perform Union
val dfToSave=dfMainOutput.select(columns: _*).union(insertdf.select(columns: _*)).withColumn("FFAction", when($"FFAction" === "O" || $"FFAction" === "I", lit("I|!|")))
【问题讨论】:
【参考方案1】:每列的数据类型必须匹配才能执行数据帧的联合。
查看您的架构,有三列不符合此要求:
AuditorOpinionOnInternalControlsId
AuditorOpinionOnGoingConcernId
IsPlayingCSRAuditorRole
更改数据类型的一种简单方法是使用withColumn
和cast
。我假设下面代码的正确类型在 dfMainOutput
数据框中:
val insertDfNew = insertdf
.withColumn("AuditorOpinionOnInternalControlsId", $"AuditorOpinionOnInternalControlsId".cast(IntegerType))
.withColumn("AuditorOpinionOnGoingConcernId", $"AuditorOpinionOnGoingConcernId".cast(BooleanType))
.withColumn("IsPlayingCSRAuditorRole", $"IsPlayingCSRAuditorRole".cast(StringType))
.withColumn("FFAction", when($"FFAction" === "O" || $"FFAction" === "I", lit("I|!|")).otherwise($"FFAction"))
val dfToSave = dfMainOutput.union(insertDfNew)
【讨论】:
另外,您可以通过以下方式进行转换 df.select(col("value").cast("string")) @BdEngineer:当然,你可以做到。如果您有一个要合并为一个的数据框列表,那么您可以这样做:dataframeList.reduce(_.union(_))
。如果您逐个计算它们,也可以在 for 循环中迭代地完成,但是您需要有一个起始数据框或创建一个具有正确架构的空数据框。
@BdEngineer:我不确定是否存在任何性能差异,但我认为应该非常相似。我发现了这个问题,其中前两个答案显示了我在上面的评论中写的内容(通过实际示例更清楚一些):***.com/questions/43489807/… 请注意,您合并的数据框必须是var
(它可以更改)而不是val
.
@BdEngineer:我不确定是什么问题。也许您可以使用代码创建一个新问题,希望我或其他人能够发现问题所在。以上是关于只能对具有兼容列类型 Spark 数据框的表执行联合的主要内容,如果未能解决你的问题,请参考以下文章