簡體   English   中英

Spark Dataframe 到 Java 類的數據集

[英]Spark Dataframe to Dataset of Java class

我想將作為 Json 讀入的數據幀轉換為給定類的數據集。 到目前為止,當我能夠編寫自己的案例類時,效果很好。

case class MyCaseClass(...)
val df = spark.read.json("path/to/json")
val ds = df.as[MyCaseClass]

def myFunction(input: MyCaseClass): MyCaseClass = {
    // Do some validation and things
    input
}

ds.map(myFunction)

但是,現在我綁定到外部 Java 類(特別是由 thrift 創建的類)。 所以這里有一個帶有自定義類的更具體的例子:

傑森:

{"a":1,"b":"1","wrapper":{"inside":"1.1", "map": {"k": "v"}}}
{"a":2,"b":"2","wrapper":{"inside":"2.1", "map": {"k": "v"}}}
{"a":3,"b":"3","wrapper":{"inside":"3.1", "map": {"k": "v"}}}

班級:

class MyInnerClass(var inside: String, var map: Map[String, String]) extends java.io.Serializable {
  def getInside(): String = {inside}
  def setInside(newInside: String) {inside = newInside}
  def getMap(): Map[String, String] = {map}
  def setMap(newMap: Map[String, String]) {map = newMap}
}

class MyClass(var a: Int, var b: String, var wrapper: MyInnerClass)  extends java.io.Serializable {
  def getA(): Int = {a}
  def setA(newA: Int) {a = newA}
  def getB(): String = {b}
  def setB(newB: String) {b = newB}
  def getWrapper(): MyInnerClass = {wrapper}
  def setWrapper(newWrapper: MyInnerClass) {wrapper = newWrapper}
}

所以我想做:

val json = spark.read.json("path/to/json")
json.as[MyClass]

但是,這會拋出:

Unable to find encoder for type stored in a Dataset.  Primitive type (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.

所以,我發現了自定義編碼器:( 這里這里

import org.apache.spark.sql.Encoders
val kryoMyClassEncoder  = Encoders.kryo[MyClass]
json.as[MyClass](kryoMyClassEncoder)

哪個拋出:

Try to map struct<a:bigint,b:string,wrapper:struct<inside:string,map:struct<k:string>>> to Tuple1, but failed as the number of fields does not line up

那么如何將 Dataframe 轉換為自定義對象 Dataset。

不要使用 kryo 編碼器,而是嘗試使用產品編碼器,即:

val productMyClassEncoder  = Encoders.product[MyClass]

在方法中使用case 類聲明時,我遇到了同樣的問題(沒有任何幫助)。 將類import spark.implicits._方法import spark.implicits._工作正常

在將數據讀取為 json 時,我們需要在使用 kryo 序列化時將架構更改為二進制類型和列名稱為“值”的單個字段

val json = spark.read.json("path/to/json").schema(newStructType().add("value",BinaryType))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM