【问题标题】:Spark - compare 2 dataframes without using hardcoded column namesSpark - 比较 2 个数据帧而不使用硬编码的列名
【发布时间】:2022-02-14 18:42:56
【问题描述】:
I need to create a way to compare 2 data frames and do not use any hardcoded data, so that I can upload at any time 2 files and compare them without changing anything.

df1
+--------------------+--------+----------------+----------+
|                  ID|colA.   |colB.           |colC      |
+--------------------+--------+----------------+----------+
|(122C8984ABF9F6EF...|       0|              10|     APPLE|
|(122C8984ABF9F6EF...|       0|              20|     APPLE|
|(122C8984ABF9F6EF...|       0|              10|    GOOGLE|
|(122C8984ABF9F6EF...|       0|              10|     APPLE|
|(122C8984ABF9F6EF...|       0|              15|   SAMSUNG|
|(122C8984ABF9F6EF...|       0|              10|     APPLE|
+--------------------+--------+----------------+----------+


df2
+--------------------+--------+----------------+----------+
|                  ID|colA.   |colB            |colC      |
+--------------------+--------+----------------+----------+
|(122C8984ABF9F6EF...|       0|              10|     APPLE|
|(122C8984ABF9F6EF...|       0|              20|     APPLE|
|(122C8984ABF9F6EF...|       0|              10|     APPLE|
|(122C8984ABF9F6EF...|       0|              30|     APPLE|
|(122C8984ABF9F6EF...|       0|              15|   SAMSUNG|
|(122C8984ABF9F6EF...|       0|              15|    GOOGLE|
+--------------------+--------+----------------+----------+

我需要比较这两个数据框并计算每列的差异。 我的输出应该是这样的:|

+--------------+-------------+-----------------+------------+------+
|Attribute Name|Total Records|Number Miss Match|% Miss Match|Status|
+--------------+-------------+-----------------+------------+------+
|      colA|            6|                0|       0.0 %|  Pass|
colB.       |           6|                3|        50 %|  Fail|
|    colC. |            6|                2|      33.3 %|  Fail||
+--------------+-------------+-----------------+------------+------+

我知道在使用硬编码列名时如何比较列,我的要求是动态比较它。 到目前为止,我所做的是从每个数据框中选择一列,但这似乎不是正确的方法。

 val columnsAll = df1.columns.map(m=>col(m))
 val df1_col1 = df1.select(df1.columns.slice(1,2).map(m=>col(m)):_*).as("Col1")
 val df2_col1 = df2.select(df2.columns.slice(1,2).map(m=>col(m)):_*).as("Col2")

【问题讨论】:

  • 当你有 2 个数据框时,总记录数是多少?
  • Total Records 是两个数据帧共有的数字,在本例中为 8。我比较了两个数据帧的行数,为“内部”,总数为 8。现在我需要比较每一列,如果有差异,请计算它们,我不知道如何在不使用它们的名称的情况下比较这些列。
  • 那么是位置依赖,要比较的关键吗?
  • 唯一可以使用的列名是ID列。

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


【解决方案1】:

这里有两种方式:

  1. spark-fast-tests 库有两种方法用于进行 DataFrame 比较:

assertSmallDataFrameEquality方法收集驱动节点上的DataFrame并进行比较

def assertSmallDataFrameEquality(actualDF: DataFrame, expectedDF: DataFrame): Unit = {
  if (!actualDF.schema.equals(expectedDF.schema)) {
    throw new DataFrameSchemaMismatch(schemaMismatchMessage(actualDF, expectedDF))
  }
  if (!actualDF.collect().sameElements(expectedDF.collect())) {
    throw new DataFrameContentMismatch(contentMismatchMessage(actualDF, expectedDF))
  }
}
  1. 使用df2.except(df1)

这2种方式的详细可以参考DataFrame equality in Apache Spark Compare two Spark dataframes

【讨论】:

  • 谢谢,这是一个很好的起点。
猜你喜欢
  • 1970-01-01
  • 2021-08-14
  • 2018-01-15
  • 2021-12-14
  • 2021-10-02
  • 1970-01-01
  • 2022-09-29
  • 2020-06-07
  • 1970-01-01
相关资源
最近更新 更多