21

Spark 数据集从 Row's 转移到EncoderPojo's/primitives 的's。Catalyst引擎使用ExpressionEncoder转换 SQL 表达式中的列。但是,似乎没有其他子类Encoder可用作我们自己的实现的模板。

下面是一个在 Spark 1.X / DataFrames 中没有在新机制下编译的代码示例:

//mapping each row to RDD tuple
df.map(row => {
    var id: String = if (!has_id) "" else row.getAs[String]("id")
    var label: String = row.getAs[String]("label")
    val channels  : Int = if (!has_channels) 0 else row.getAs[Int]("channels")
    val height  : Int = if (!has_height) 0 else row.getAs[Int]("height")
    val width : Int = if (!has_width) 0 else row.getAs[Int]("width")
    val data : Array[Byte] = row.getAs[Any]("data") match {
      case str: String => str.getBytes
      case arr: Array[Byte@unchecked] => arr
      case _ => {
        log.error("Unsupport value type")
        null
      }
    }
    (id, label, channels, height, width, data)
  }).persist(StorageLevel.DISK_ONLY)

}

我们得到一个编译器错误

Error:(56, 11) Unable to find encoder for type stored in a Dataset.
Primitive types (Int, String, etc) and Product types (case classes) are supported 
by importing spark.implicits._  Support for serializing other types will be added in future releases.
    df.map(row => {
          ^

那么,不知何故/某处应该有办法

  • 定义/实现我们的自定义编码器
  • DataFrame在(现在是类型的 Dataset Row)上执行映射时应用它
  • 注册编码器以供其他自定义代码使用

我正在寻找成功执行这些步骤的代码。

4

3 回答 3

22

据我所知,自 1.6 和如何在数据集中存储自定义对象中描述的解决方案以来没有任何变化?是唯一可用的选项。尽管如此,您当前的代码应该可以与产品类型的默认编码器一起正常工作。

要了解为什么您的代码在 1.x 中有效而在 2.0.0 中可能无效,您必须检查签名。在 1.xDataFrame.map中是一个接受函数Row => T并转换RDD[Row]RDD[T].

在 2.0.0中也DataFrame.map采用类型函数Row => T,但将Dataset[Row](aka DataFrame) 转换为Dataset[T]因此T需要Encoder. 如果您想获得“旧”行为,您应该RDD明确使用:

df.rdd.map(row => ???)

如需Dataset[Row] map查看尝试将数据帧行映射到更新行时出现编码器错误

于 2016-06-13T04:42:32.380 回答
2

您是否导入了隐式编码器?

导入 spark.implicits._

http://spark.apache.org/docs/2.0.0-preview/api/scala/index.html#org.apache.spark.sql.Encoder

于 2016-06-11T23:56:22.987 回答
0

我导入了 spark.implicits._ 其中 spark 是 SparkSession,它解决了错误并导入了自定义编码器。

此外,编写自定义编码器是一种我没有尝试过的方法。

工作解决方案: - 创建 SparkSession 并导入以下内容

导入 spark.implicits._

于 2018-11-28T03:05:16.363 回答