数据框中ArrayType列之间的差异

时间:2016-12-15 08:50:03

标签: scala apache-spark apache-spark-sql spark-dataframe

我有2个ArrayType列的数据框。 我想找到列之间的区别。 column1将始终具有值,而column2可能具有空数组。 我创建了以下udf,但它无法正常工作

df.show()提供以下记录

SampleData:

["Test", "Test1","Test3", "Test2"], ["Test", "Test1"]

代码:

sc.udf.register("diff", (value: Column,value1: Column)=>{ 
                        value.asInstanceOf[Seq[String]].diff(value1.asInstanceOf[Seq[String]])          
                    })  

输出:

["Test2","Test3"]

Spark版本1.4.1 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

  

column1将始终具有值,而column2可能具有空数组。

     

您的评论 :它提供了所有值的值 - undefined_variable

示例1:

让我们看看像这样的小例子......

   val A = Seq(1,1)

 A: Seq[Int] = List(1, 1)

 val B = Seq.empty

 B: Seq[Nothing] = List()

A diff B

 res0: Seq[Int] = List(1, 1)

如果您执行collection.SeqLike.diff,那么您将获得A值,如示例所示。 根据scala,这是非常有效的案例,因为你告诉你总是得到value这是seq。

另外,反向情况就是这样......

 B diff A

 res1: Seq[Nothing] = List()

如果您使用Spark udf执行上述操作,则会产生相同的结果。

编辑:(如果你修改了你的例子,一个数组不是空的情况)

示例2:

 val p = Seq("Test", "Test1","Test3", "Test2")

 p: Seq[String] = List(Test, Test1, Test3, Test2)

 val q = Seq("Test", "Test1")

 q: Seq[String] = List(Test, Test1)

 p diff q

 res2: Seq[String] = List(Test3, Test2)

这是您的预期输出,如您的示例所示。

反向案例:我认为这是你所得到的,这是你不期望的。

q diff p

 res3: Seq[String] = List()

答案 1 :(得分:1)

您需要将udf更改为:

val diff_udf = udf { ( a:  Seq[String], 
                       b:  Seq[String]) => a diff b }

然后这个有效:

import org.apache.spark.sql.functions.col
df.withColumn("diff",
  diff_udf(col("col1"), col("col2"))).show
+--------------------+-----------------+------------------+
|                col1|             col2|              diff|
+--------------------+-----------------+------------------+
|List(Test, Test1,...|List(Test, Test1)|List(Test3, Test2)|
+--------------------+-----------------+------------------+

数据

val df = sc.parallelize(Seq((List("Test", "Test1","Test3", "Test2"), 
                             List("Test", "Test1")))).toDF("col1", "col2")