【问题标题】:Dataframe to Dataset which has type Any数据框到数据集,其类型为 Any
【发布时间】:2023-03-29 18:12:02
【问题描述】:

我最近从 Spark 1.6 迁移到了 Spark 2.X,并且我也想在可能的情况下从 Dataframes 迁移到 Datasets。我试过这样的代码

case class MyClass(a : Any, ...)

val df = ...
df.map(x => MyClass(x.get(0), ...))

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

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

java.lang.ClassNotFoundException: scala.Any

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

【问题讨论】:

    标签: apache-spark dataframe apache-spark-sql apache-spark-dataset


    【解决方案1】:

    除非你对limited and ugly workarounds 感兴趣,比如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 不完全兼容,并且会带来显着的性能和存储损失。

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

    【讨论】:

      猜你喜欢
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多