Dataframe.map需要的结果超过数据集

时间:2016-07-05 04:28:43

标签: scala apache-spark dataframe

我正在使用scala和spark,并使用简单的dataframe.map来生成所需的数据转换。但是,我需要使用修改后的原始数据提供额外的数据行。我如何使用dataframe.map来解决这个问题。

例如: 数据集来自:

  • id,姓名,年龄
  • 1,john,23
  • 2,彼得,32

如果年龄< 25默认为25。

数据集:

  • id,姓名,年龄
  • 1,john,25
  • 1,john,-23
  • 2,彼得,32

1 个答案:

答案 0 :(得分:0)

&#39; UnionAll&#39;处理它?<​​/ p>

例如。

   df1 = original dataframe
   df2 = transformed df1

   df1.unionAll(df2) 

编辑:使用unionAll()

实现
val df1=sqlContext.createDataFrame(Seq(  (1,"john",23) , (2,"peter",32) )).
           toDF( "id","name","age")

def udfTransform= udf[Int,Int] { (age) => if (age<25) 25 else age }

val df2=df1.withColumn("age2", udfTransform($"age")).
            where("age!=age2").
            drop("age2")

df1.withColumn("age", udfTransform($"age")).
    unionAll(df2).
    orderBy("id").
    show()

+---+-----+---+
| id| name|age|
+---+-----+---+
|  1| john| 25|
|  1| john| 23|
|  2|peter| 32|
+---+-----+---+

注意:实现与最初提出的(天真)解决方案略有不同。魔鬼总是在细节中!

编辑2 :使用嵌套数组实现并爆炸

val df1=sx.createDataFrame(Seq(  (1,"john",23) , (2,"peter",32) )).
           toDF( "id","name","age")
def udfArr= udf[Array[Int],Int] { (age) => 
               if (age<25) Array(age,25) else Array(age) }

val df2=df1.withColumn("age", udfArr($"age"))

df2.show()
+---+-----+--------+
| id| name|     age|
+---+-----+--------+
|  1| john|[23, 25]|
|  2|peter|    [32]|
+---+-----+--------+


df2.withColumn("age",explode($"age") ).show()
+---+-----+---+
| id| name|age|
+---+-----+---+
|  1| john| 23|
|  1| john| 25|
|  2|peter| 32|
+---+-----+---+