Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spark:比较两个数据集_Java_Apache Spark - Fatal编程技术网

Java Spark:比较两个数据集

Java Spark:比较两个数据集,java,apache-spark,Java,Apache Spark,我正在做一个spark工作,从两个不同的位置读取拼花地板文件中的数据。这些拼花地板文件由两个不同的源生成,但源相同。 我想比较这两个拼花地板文件中的数据集,看看是否有任何列值被删除 有没有办法比较两个数据集并显示不匹配的列 数据集parquetFile=spark 阅读 .parquetfile//file1.parquet; 在非常高的级别上,您可以尝试以下操作: 将数据从两个位置加载到单独的数据帧df1和df2中。 将id字段上的df1和df2连接到df3 为df3编写映射函数,在其中比较

我正在做一个spark工作,从两个不同的位置读取拼花地板文件中的数据。这些拼花地板文件由两个不同的源生成,但源相同。 我想比较这两个拼花地板文件中的数据集,看看是否有任何列值被删除

有没有办法比较两个数据集并显示不匹配的列

数据集parquetFile=spark 阅读 .parquetfile//file1.parquet;

在非常高的级别上,您可以尝试以下操作:

将数据从两个位置加载到单独的数据帧df1和df2中。 将id字段上的df1和df2连接到df3 为df3编写映射函数,在其中比较联接的左侧和右侧。 map函数的返回结果可能类似于包含行id和不匹配的列名/值对列表的元组。 在UI中存储结果或预览。
我的解决方案是Scala,但你也可以用Java来解决,因为想法是一样的

当比较spark中的两个数据集/数据帧时,我可以想到多种方法,你可以进行df。除了两次,即A-B和B-A,然后连接两个结果数据帧,但这是一个大量的洗牌,如果列数增加,则会占用大量存储下面的方法是最简单的,只需要一次洗牌,即使有数千个专栏和数百万条记录,它也能发挥魅力:

  case class Person(name: String, age: Long)
  import spark.implicits._

  def main(args: Array[String]): Unit = {

    val source = Seq(Person("Andy", 32), Person("Farhan", 26), Person("John", 23)).toDS().toDF
    val target = Seq(Person("Andy", 32), Person("Farhan", 25), Person("John", 23)).toDS().toDF

    compareTwoDatasets(spark, source, target, "name").show(10, false)

  }

  def compareTwoDatasets(spark: SparkSession, sourceDS: Dataset[Row], targetDS: Dataset[Row], uniqueColumnName: String) = {

    val source = sourceDS.map(sourceRow => (sourceRow.getAs(uniqueColumnName).toString, sourceRow.mkString("|"))).toDF(uniqueColumnName, "source_record")
    val target = targetDS.map(targetRow => (targetRow.getAs(uniqueColumnName).toString, targetRow.mkString("|"))).toDF(uniqueColumnName, "target_record")
    val columns = sourceDS.columns
    source
      .join(target, uniqueColumnName)
      .where($"source_record" =!= $"target_record")
      .flatMap { row =>
        val sourceArray = row.getAs[String]("source_record").split("\\|", -1)
        val targetArray = row.getAs[String]("target_record").split("\\|", -1)
        val commonValue = row.getAs[String](uniqueColumnName)
        List(columns, sourceArray, targetArray)
          .transpose
          .filter(x => x(1) != x(2))
          .map((commonValue, _))

      }.toDF(uniqueColumnName, "mismatch_column_source_target")

  }
输出:

+------+-----------------------------+
|name  |mismatch_column_source_target|
+------+-----------------------------+
|Farhan|[age, 26, 25]                |
+------+-----------------------------+    

第二列中的值将是不匹配的列名、源值及其对应的目标值。

在我看来,最好回答这个问题,但使用DF和SCALA以及更通用的方法,这样也可以工作

例如,模拟输入:

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()

gives:

+------+-----------+------+-----------+--------+------------+------------+   
|  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|
+------+-----------+------+-----------+--------+------------+------------+

接受答案可能是个好主意?Project有一个数据集比较模块,可以帮助您。可以用作库。这不是很通用,我宁愿使用