2015-10-18 89 views
5

我有一个数据框,列中有:user, address1, address2, address3, phone1, phone2等等。 我想这个数据帧转换为 - user, address, phone where address = Map("address1" -> address1.value, "address2" -> address2.value, "address3" -> address3.value)使用Spark Dataframe scala将多个不同的列转换为Map列

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

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

,但我不知道怎么把它添加到我的DF。

我是新来的火花和斯卡拉,真的可以在这里使用一些帮助。

回答

6

星火> = 2.0

可以跳过udf和使用mapcreate_map在Python)SQL函数:

import org.apache.spark.sql.functions.map 

df.select(
    map(mapData.map(c => lit(c) :: col(c) :: Nil).flatten: _*).alias("a_map") 
) 

星火< 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的,是结构,而不是地图领域:

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

的最大优点是它可以轻松处理值不同的类型。

相关问题