簡體   English   中英

將數據框的每一行轉換為地圖

[英]convert each row of dataframe to a map

我有一個數據框,其中A和B列的類型為String。 假設下面的數據框

+--------+
|A  | B  |
|1a | 1b |
|2a | 2b |

我想添加第三列,以創建A和B列的地圖

+-------------------------+
|A  | B  |  C             |
|1a | 1b | {A->1a, B->1b} |
|2a | 2b | {A->2a, B->2b} |

我正在嘗試通過以下方式進行操作。 我有udf,它接受一個數據框並返回地圖

val test = udf((dataFrame: DataFrame) => {
val result = new mutable.HashMap[String, String]
dataFrame.columns.foreach(col => {
  result.put(col, dataFrame(col).asInstanceOf[String])
})
result
})

我以以下方式調用此udf,因為我試圖將DataSet作為文字傳遞,所以引發RunTimeException

df.withColumn("C", Helper.test(lit(df.select(df.columns.head, df.columns.tail: _*)))

我不想將df('a')df('b')傳遞給我的助手udf,因為我希望它們成為我可以選擇的通用列列表。 有指針嗎?

地圖方式

您可以將map 內置函數用作

import org.apache.spark.sql.functions._
val columns = df.columns
df.withColumn("C", map(columns.flatMap(x => Array(lit(x), col(x))): _*)).show(false)

這應該給你

+---+---+---------------------+
|A  |B  |C                    |
+---+---+---------------------+
|1a |1b |Map(A -> 1a, B -> 1b)|
|2a |2b |Map(A -> 2a, B -> 2b)|
+---+---+---------------------+

udf方式

或者您可以將udf定義為

//collecting column names to be used in the udf
val columns = df.columns
//definining udf function
import org.apache.spark.sql.functions._
def createMapUdf = udf((names: Seq[String], values: Seq[String])=> names.zip(values).toMap)
 //calling udf function 
df.withColumn("C", createMapUdf(array(columns.map(x => lit(x)): _*), array(col("A"), col("B")))).show(false)

我希望答案是有幫助的

@ Ramesh Maharjan-您的答案已經很好,我的答案是使用字符串插值以動態方式使您的UDF答案。

D欄以動態方式給出了這一點。

df.withColumn("C", createMapUdf(array(columns.map(x => lit(x)): _*), 
array(col("A"), col("B"))))
.withColumn("D", createMapUdf(array(columns.map(x => lit(x)): _*), 
array(columns.map(x => col(s"$x") ): _* ))).show()

暫無
暫無

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

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