数据帧到类型为“任意”的数据集



我最近从Spark 1.6迁移到Spark 2.X,如果可能的话,我也想从数据帧移动到数据集。我尝试了这样的代码

case class MyClass(a : Any, ...)
val df = ...
df.map(x => MyClass(x.get(0), ...))

如您所见,MyClass有一个类型的字段 Any ,因为我不知道在编译时我用x.get(0)检索的字段的类型。它可以是长、字符串、整数等。

但是,当我尝试执行类似于上面看到的代码时,我得到一个异常:

java.lang.ClassNotFoundException: scala.Any

通过一些调试,我意识到引发了异常,不是因为我的数据是 Any 型,而是MyClass具有Any类型。那么我该如何使用数据集呢?

除非您对有限且丑陋的解决方法感兴趣,例如Encoders.kryo

import org.apache.spark.sql.Encoders
case class FooBar(foo: Int, bar: Any)
spark.createDataset(
  sc.parallelize(Seq(FooBar(1, "a")))
)(Encoders.kryo[FooBar])

spark.createDataset(
  sc.parallelize(Seq(FooBar(1, "a"))).map(x => (x.foo, x.bar))
)(Encoders.tuple(Encoders.scalaInt, Encoders.kryo[Any]))

你没有。Dataset中的所有字段/列都必须是已知的同类类型,范围中存在隐式Encoder。那里根本没有Any的地方。

UDT API 提供了更大的灵活性,并允许有限的多态性,但它是私有的,与Dataset API 不完全兼容,并且会带来显着的性能和存储损失。

如果对于给定的执行,所有相同类型的值,您当然可以创建专门的类并决定在运行时使用哪一个类。

相关内容

  • 没有找到相关文章

最新更新