Как найти точные и неточные совпадения между двумя фреймами данных? - PullRequest
0 голосов
/ 10 мая 2018

У меня есть два кадра данных.

df1

+--------+-------------------
|id  | amount       | fee   | 
|1   | 10.00        | 5.0   |
|2   | 20.0         | 3.0   |
|3   | 90           | 130.0 |
|4   | 120.0        | 35.0  |

df2

+--------+--------------------
|exId  | exAmount     | exFee| 
|1     | 10.00        | 5.0  |
|2     | 20.0         | 3.0  |
|3     | 20.0         | 3.0  |
|4     | 120.0        | 3.0  |

Мне нужно выполнить следующие операции

  1. Найти общие строки, в которых все три столбца соответствуют, например, id 1,2 в приведенном выше примере.
  2. Найдите общие строки, в которых (id, exId) совпадают, но другие не соответствуют, например, например. 3 и 4 в приведенном выше примере. Было бы полезно, если бы мы определили, какой из столбцов не совпадает.

Таким образом, результат будет выглядеть так

точное совпадение

+--------+---------------------------------------------
|id  | amount       | fee   | exId | exAmount | exFee | 
|1   | 10.00        | 5.0   | 1    |  10.00   | 5.0   |  
|2   | 20.0         | 3.0   | 2    |  20.00   | 3.0   |
+--------+---------------------------------------------

неточное совпадение

+--------+------------------------------------------------------------
|id  | amount       | fee   | exId | exAmount | exFee | mismatchFields|
|3   | 90.00        | 130.0 | 3    |  20.00   | 3.0   |  [fee, amount]|
|4   | 120.0        | 35.0  | 4    |  120.00  | 3.0   |  [fee]        |
+--------+------------------------------------------------------------  

Есть мысли?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Найти общие строки, в которых все три столбца соответствуют, например, id 1,2 в приведенном выше примере.

это довольно просто, вам просто нужно проверить все столбцы на равенство при объединении

df1.join(df2, df1("id") === df2("exId") && df1("amount") === df2("exAmount") && df1("fee") === df2("exFee")).show(false)

что должно дать вам

+---+------+---+----+--------+-----+
|id |amount|fee|exId|exAmount|exFee|
+---+------+---+----+--------+-----+
|1  |10.00 |5.0|1   |10.00   |5.0  |
|2  |20.0  |3.0|2   |20.0    |3.0  |
+---+------+---+----+--------+-----+

Найдите общие строки, в которых (id, exId) совпадают, но другие не соответствуют, например, например. 3 и 4 в приведенном выше примере. Было бы полезно, если бы мы определили, какой из столбцов не совпадает.

для этого вам нужно проверить равенство для первого столбца , но en-равенство для остальных двух столбцов и выполнить некоторое при условии получения последнего столбца

import org.apache.spark.sql.functions._
df1.join(df2, df1("id") === df2("exId") && (df1("amount") =!= df2("exAmount") || df1("fee") =!= df2("exFee")))
.withColumn("mismatchFields", when(col("amount") =!= col("exAmount") && col("fee") =!= col("exFee"), array(lit("amount"), lit("fee"))).otherwise(
  when(col("amount") === col("exAmount") && col("fee") =!= col("exFee"), array(lit("fee"))).otherwise(array(lit("amount")))
)).show(false)

что должно дать вам

+---+------+-----+----+--------+-----+--------------+
|id |amount|fee  |exId|exAmount|exFee|mismatchFields|
+---+------+-----+----+--------+-----+--------------+
|3  |90    |130.0|3   |20.0    |3.0  |[amount, fee] |
|4  |120.0 |35.0 |4   |120.0   |3.0  |[fee]         |
+---+------+-----+----+--------+-----+--------------+

Надеюсь, ответ полезен

0 голосов
/ 10 мая 2018
  1. Сначала выполните внутреннее объединение и получите совпадающие данные из обоих кадров на основе идентификатора.
  2. Создание нового соответствия столбца на основе суммы и комиссии
  3. Фильтр по столбцу совпадений

val joinedDF = df1.join(df2,df1.col("id")===df2.col("exId")) .withColumn("match",when(col("fee")===col("exFee") && col("amount")===col("exAmount"),lit(1)) .otherwise(lit(0)))

Сопоставимые данные:

val matchedDF = joinedDF.filter("match=1")

Несоответствующие данные:

val notMatchedDF = joinedDF.filter("match=0")
                        .withColumn("mismatchedFields",when(col("fee")!=col("exFee") &&
                                       col("amount")!=col("exAmount"),array("fee","amount"))
                                      .otherwise(when(col("fee")!=col("exFee") ,array("fee"))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...