【问题标题】:Spark createDataframe from RDD of objects, column orderSpark createDataframe from RDD of objects, column order
【发布时间】:2017-10-07 14:54:52
【问题描述】:

我正在尝试将我的自定义对象(Java 类)的 RDD 转换为 Dataframe,我只是使用方法 hiveContext.createDataframe 指定对象的类。问题是数据框是用一些奇怪的顺序创建的列,一旦我将 DF 写入 Hive,值就在错误的列中。 这是我的代码:

var objectRDD = tableDF.map((r: Row) => new Attuatore(r(0),r(1)...)) [.. operations with the RDD ..] val resultDF = hiveContext.createDataFrame(objectRDD, classOf[Attuatore]) resultDF.write.mode("append").saveAsTable(outputTable)

到目前为止,我发现的唯一解决方案是将字段按正确的顺序转换回 RDD[Attuatore] 到 RDD[Row],然后调用 createDataFrame() 指定架构,但因为我必须这样做这有很多类,我更喜欢第一种方法来拥有更简洁的代码。

【问题讨论】:

    标签: java scala apache-spark dataframe


    【解决方案1】:

    正如 HiveContext.createDataFrame 的文档所述

    由于 Java Bean 中的字段没有保证顺序, SELECT * 查询将以未定义的顺序返回列。

    因此,如果您需要按定义的顺序放置字段,则必须明确地进行,例如

    val MY_COLUMNS = Seq("field1", "field2", ...)
    val conformedDF = resultDF.select(MY_COLUMNS.map(col(_)):_*)
    conformedDF.write...
    

    【讨论】:

    • 你的代码对我不起作用,它说预期的 Seq[Column] found Seq[Any],但我认为只使用 val conformedDF = resultDF.select("field1", "field2" , ...) 将工作
    • 抱歉,有错字,已修复。我的期望是您将从其他地方(反射、元数据等)获取列列表(按所需顺序),而不是内联硬编码它们。显然后者更简单,如果你同意的话。
    • 我从 Java 类中获取 cols,您知道如何转换 Array[String] 以便将其传递给 select 方法吗?在妈妈那里。我正在使用 (cols.head,cols.tail:_*) 其中 cols 是数组(我不知道 Scala)
    • 您可以在 Array 上使用 toSeq 方法,例如def conform(df: DataFrame, columns: Array[String]): DataFrame = { df.select(columns.toSeq.map(col(_)):_*) } 但头部、尾部重载也可以,只要您始终至少有一列。
    • 非常感谢您的解释
    猜你喜欢
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    相关资源
    最近更新 更多