Ответ 1
Spark 2.0. 0+:
UserDefinedType
был UserDefinedType
в Spark 2.0.0, и на данный момент он не поддерживает замену Dataset
.
См. SPARK-14155 (Hide UserDefinedType в Spark 2.0)
В большинстве случаев статически типизированный Dataset
может служить заменой. Ожидается Jira SPARK-7768, чтобы снова открыть UDT API с целевой версией 2.4.
См. Также Как сохранить пользовательские объекты в наборе данных?
Искры <2.0.0
Есть ли возможность добавить или определить схему для определенных типов (здесь введите Some)?
Думаю, ответ зависит от того, насколько вам это нужно. Похоже, что можно создать UserDefinedType
но он требует доступа к DeveloperApi
и не совсем прост или хорошо документирован.
import org.apache.spark.sql.types._
@SQLUserDefinedType(udt = classOf[SomeUDT])
sealed trait Some
case object AType extends Some
case object BType extends Some
class SomeUDT extends UserDefinedType[Some] {
override def sqlType: DataType = IntegerType
override def serialize(obj: Any) = {
obj match {
case AType => 0
case BType => 1
}
}
override def deserialize(datum: Any): Some = {
datum match {
case 0 => AType
case 1 => BType
}
}
override def userClass: Class[Some] = classOf[Some]
}
Вероятно, вы должны переопределить hashCode
и equals
.
Его коллега PySpark может выглядеть так:
from enum import Enum, unique
from pyspark.sql.types import UserDefinedType, IntegerType
class SomeUDT(UserDefinedType):
@classmethod
def sqlType(self):
return IntegerType()
@classmethod
def module(cls):
return cls.__module__
@classmethod
def scalaUDT(cls): # Required in Spark < 1.5
return 'net.zero323.enum.SomeUDT'
def serialize(self, obj):
return obj.value
def deserialize(self, datum):
return {x.value: x for x in Some}[datum]
@unique
class Some(Enum):
__UDT__ = SomeUDT()
AType = 0
BType = 1
В Spark <1.5 Python UDT требует сопряженного Scala UDT, но похоже, что это больше не относится к 1.5.
Для простого UDT вы можете использовать простые типы (например, IntegerType
вместо целых Struct
).