簡體   English   中英

使用數據框的架構生成Spark Map數據框

[英]Spark map dataframe using the dataframe's schema

我有一個從JSON對象創建的數據框。 我可以查詢此數據幀並將其寫入鑲木地板。

由於我推斷出架構,因此我不一定知道數據框中的內容。

有沒有辦法將列名列出來或使用其自己的模式映射數據框?

// The results of SQL queries are DataFrames and support all the normal  RDD operations.
// The columns of a row in the result can be accessed by field index:
df.map(t => "Name: " + t(0)).collect().foreach(println)

// or by field name:
df.map(t => "Name: " + t.getAs[String]("name")).collect().foreach(println)

// row.getValuesMap[T] retrieves multiple columns at once into a Map[String, T]
df.map(_.getValuesMap[Any](List("name", "age"))).collect().foreach(println)
// Map("name" -> "Justin", "age" -> 19)

我想做類似的事情

df.map (_.getValuesMap[Any](ListAll())).collect().foreach(println)
// Map ("name" -> "Justin", "age" -> 19, "color" -> "red")

不知道列的實際數量或名稱。

好吧,您可以,但是結果卻毫無用處:

val df = Seq(("Justin", 19, "red")).toDF("name", "age", "color")

def getValues(row: Row, names: Seq[String]) = names.map(
  name => name -> row.getAs[Any](name)
).toMap

val names = df.columns
df.rdd.map(getValues(_, names)).first

// scala.collection.immutable.Map[String,Any] = 
//   Map(name -> Justin, age -> 19, color -> red)

要獲得實際有用的東西,可以在SQL類型和Scala類型之間進行適當的映射。 在簡單的情況下這並不難,但在一般情況下卻很難。 例如,內置類型可用於表示任意struct 可以使用一些元編程來做到這一點,但是可以說這並不值得大驚小怪。

您可以使用隱式Encoder並在DataFrame本身上執行映射:

implicit class DataFrameEnhancer(df: DataFrame) extends Serializable {
    implicit val encoder = RowEncoder(df.schema)

    implicit def mapNameAndAge(): DataFrame = {
       df.map(row => (row.getAs[String]("name") -> row.getAs[Int]("age")))
    }
}

然后像這樣在您的數據框上調用它:

val df = Seq(("Justin", 19, "red")).toDF("name", "age", "color")
df.mapNameAndAge().first

這樣,您不必將DataFrame轉換為RDD(在某些情況下,您不想從磁盤上加載整個DF,只需加載某些列,但是無論如何,RDD轉換都會迫使您執行此操作。 ,您使用的是Encoder而不是Kryo(或其他Java SerDes),速度更快。

希望能幫助到你 :-)

暫無
暫無

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

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