使用Spark Dataframe scala将多个不同的列转换为Map列



我有一个列:user, address1, address2, address3, phone1, phone2等的数据框架。我想把这个数据帧转换成- user, address, phone where address = Map("address1" -> address1.value, "address2" -> address2.value, "address3" -> address3.value)

我能够将列转换为映射使用:

val mapData = List("address1", "address2", "address3")
df.map(_.getValuesMap[Any](mapData))

但我不确定如何将此添加到我的df。

我是spark和scala的新手,可能需要一些帮助。

火花> = 2.0

可以跳过udf,使用map (Python中的create_map) SQL函数:

import org.apache.spark.sql.functions.map
df.select(
  map(mapData.map(c => lit(c) :: col(c) :: Nil).flatten: _*).alias("a_map")
)

火花& lt;2.0

据我所知,没有直接的方法来做这件事。您可以像这样使用UDF:
import org.apache.spark.sql.functions.{udf, array, lit, col}
val df = sc.parallelize(Seq(
  (1L, "addr1", "addr2", "addr3")
)).toDF("user", "address1", "address2", "address3")
val asMap = udf((keys: Seq[String], values: Seq[String]) => 
  keys.zip(values).filter{
    case (k, null) => false
    case _ => true
  }.toMap)
val keys = array(mapData.map(lit): _*)
val values = array(mapData.map(col): _*)
val dfWithMap = df.withColumn("address", asMap(keys, values))

另一个不需要udf的选项是struct field而不是map:

val dfWithStruct = df.withColumn("address", struct(mapData.map(col): _*))

最大的优点是它可以很容易地处理不同类型的值

相关内容

  • 没有找到相关文章