gpt4 book ai didi

scala - Spark 数据框到密封特征类型

转载 作者:行者123 更新时间:2023-12-02 01:19:52 25 4
gpt4 key购买 nike

我有一些数据存储为 Parquet 文件和与数据模式匹配的案例类。 Spark 可以很好地处理常规产品类型,所以如果我有

case class A(s:String, i:Int)

我可以轻松做到

spark.read.parquet(file).as[A]

但据我了解,Spark 不处理析取类型,因此当我的 parquet 中有枚举时,之前编码为整数,以及像这样的 scala 表示形式

sealed trait E
case object A extends E
case object B extends E

我做不到

spark.read.parquet(file).as[E]
// java.lang.UnsupportedOperationException: No Encoder found for E

到目前为止是有道理的,但后来,可能太天真了,我尝试了

implicit val eEncoder = new org.apache.spark.sql.Encoder[E] {
def clsTag = ClassTag(classOf[E])
def schema = StructType(StructField("e", IntegerType, nullable = false)::Nil)
}

我仍然得到相同的“没有为 E 找到编码器”:(

此时我的问题是,为什么范围内隐式缺失? (或者不被识别为编码器[E]),即使它被识别,这样的接口(interface)如何让我真正解码数据?我仍然需要将值映射到正确的案例对象。

我确实读过a related answer上面写着“TL;DR 目前还没有好的解决方案,并且考虑到 Spark SQL/数据集的实现,在可预见的将来不太可能有一个解决方案。”但我很难理解为什么自定义编码器无法做到这一点。

最佳答案

But I'm struggling to understand why a custom Encoder couldn't do the trick.

两个主要原因:

  • 没有用于自定义编码器的 API。公开可用的只有“二进制”Kryo 和 Java Encoders,它们会创建无用的(在 DataFrame/Dataset[Row] 的情况下)blob,且不包含任何内容。支持任何有意义的 SQL/DataFrame 操作。

    这样的代码可以正常工作

    import org.apache.spark.sql.Encoders

    spark.createDataset(Seq(A, B): Seq[E])(Encoders.kryo[E])

    但这只不过是一种好奇心。

  • DataFrame 是一个列式存储。从技术上讲,可以在此结构之上对类型层次结构进行编码(私有(private) UserDefinedType API 就是这样做的),但它很麻烦(因为您必须为所有可能的变体提供存储,例如参见 How to define schema for custom type in Spark SQL? )而且效率低下(一般来说,复杂类型在 Spark SQL 中多少是二等公民,并且许多优化无法通过复杂模式实现,可能会在未来发生变化)。

    在更广泛的意义上,DataFrame API 是有效的关系型 API(如 relational algebra ),并且元组(关系的主要构建 block )根据定义是同质的,因此通过扩展,在 SQL/DataFrame API,用于异构结构。

关于scala - Spark 数据框到密封特征类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50926555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com