比较Spark中的两个数据帧

时间:2018-06-26 13:58:36

标签: scala apache-spark dataframe

我正在使用except()比较spark中的两个数据帧。

例如:df.except(df2)

我将从df2获取df中所有不可用的记录。但是,我也想列出不匹配的字段详细信息。

例如:

df:
------------------
id,name,age,city
101,kp,28,CHN
------------------

df2:
-----------------
id,name,age,city
101,kp,28,HYD
----------------

预期输出:

df3
--------------------------
id,name,age,city,diff
101,kp,28,CHN,City is not matching
--------------------------------

我该如何实现?

2 个答案:

答案 0 :(得分:1)

较新的版本再次尝试上述操作,但不太可能,但是使用JOIN而不是except。我力所能及。

我相信它可以满足您的需求,并考虑到一个数据集中是否存在某些东西。

在Databricks下运行。

case class Person(personid: Int, personname: String, cityid: Int)
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.functions._

val df1 = Seq(
     Person(0, "AgataZ", 0),
     Person(1, "Iweta", 0),
     Person(2, "Patryk", 2),
     Person(9999, "Maria", 2),
     Person(5, "John", 2),
     Person(6, "Patsy", 2),
     Person(7, "Gloria", 222), 
     Person(3333, "Maksym", 0)).toDF

val df2 = Seq(
     Person(0, "Agata", 0),
     Person(1, "Iweta", 0),
     Person(2, "Patryk", 2),
     Person(5, "John", 2),
     Person(6, "Patsy", 333),
     Person(7, "Gloria", 2), 
     Person(4444, "Hans", 3)).toDF

val joined = df1.join(df2, df1("personid") === df2("personid"), "outer") 
val newNames = Seq("personId1", "personName1", "personCity1", "personId2", "personName2", "personCity2")
val df_Renamed = joined.toDF(newNames: _*)

// Some deliberate variation shown in approach for learning 
val df_temp = df_Renamed.filter($"personCity1" =!= $"personCity2" || $"personName1" =!= $"personName2" || $"personName1".isNull || $"personName2".isNull || $"personCity1".isNull || $"personCity2".isNull).select($"personId1", $"personName1".alias("Name"), $"personCity1", $"personId2", $"personName2".alias("Name2"), $"personCity2").  withColumn("PersonID", when($"personId1".isNotNull, $"personId1").otherwise($"personId2"))

val df_final = df_temp.withColumn("nameChange ?", when($"Name".isNull or $"Name2".isNull or $"Name" =!= $"Name2", "Yes").otherwise("No")).withColumn("cityChange ?", when($"personCity1".isNull or $"personCity2".isNull or $"personCity1" =!= $"personCity2", "Yes").otherwise("No")).drop("PersonId1").drop("PersonId2")

df_final.show()

给予:

+------+-----------+------+-----------+--------+------------+------------+
|  Name|personCity1| Name2|personCity2|PersonID|nameChange ?|cityChange ?|
+------+-----------+------+-----------+--------+------------+------------+
| Patsy|          2| Patsy|        333|       6|          No|         Yes|
|Maksym|          0|  null|       null|    3333|         Yes|         Yes|
|  null|       null|  Hans|          3|    4444|         Yes|         Yes|
|Gloria|        222|Gloria|          2|       7|          No|         Yes|
| Maria|          2|  null|       null|    9999|         Yes|         Yes|
|AgataZ|          0| Agata|          0|       0|         Yes|          No|
+------+-----------+------+-----------+--------+------------+------------+

答案 1 :(得分:0)

使用相交获取两个数据框的通用值,然后构建不匹配的逻辑

intersect-返回一个仅包含此数据集和另一个数据集中的行的新数据集。

df.intersect(df2)
  • 返回一个新的RDD,其中包含源数据集中的元素和参数的交集。

  • intersection(anotherrdd)返回两个DF中都存在的元素。

  • intersection(anotherrdd)删除所有重复项,包括在单个DF中重复的