Как сравнить два идентично структурированных кадра данных для расчета различий строк - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть следующие два идентично структурированных фрейма данных с общим идентификатором.

val originalDF = Seq((1,"gaurav","jaipur",550,70000),(2,"sunil","noida",600,80000),(3,"rishi","ahmedabad",510,65000))
                .toDF("id","name","city","credit_score","credit_limit")
scala> originalDF.show(false)
+---+------+---------+------------+------------+
|id |name  |city     |credit_score|credit_limit|
+---+------+---------+------------+------------+
|1  |gaurav|jaipur   |550         |70000       |
|2  |sunil |noida    |600         |80000       |
|3  |rishi |ahmedabad|510         |65000       |
+---+------+---------+------------+------------+
val changedDF= Seq((1,"gaurav","jaipur",550,70000),(2,"sunil","noida",650,90000),(4,"Joshua","cochin",612,85000))
                .toDF("id","name","city","credit_score","credit_limit")
scala> changedDF.show(false)
+---+------+------+------------+------------+
|id |name  |city  |credit_score|credit_limit|
+---+------+------+------------+------------+
|1  |gaurav|jaipur|550         |70000       |
|2  |sunil |noida |650         |90000       |
|4  |Joshua|cochin|612         |85000       |
+---+------+------+------------+------------+

Поэтому я написал один udf для расчета изменения значений столбцов.

val diff = udf((col: String, c1: String, c2: String) => if (c1 == c2) "" else col )
val somedf=changedDF.alias("a").join(originalDF.alias("b"), col("a.id") === col("b.id")).withColumn("diffcolumn", split(concat_ws(",",changedDF.columns.map(x => diff(lit(x), changedDF(x), originalDF(x))):_*),","))
scala> somedf.show(false)
+---+------+------+------------+------------+---+------+------+------------+------------+----------------------------------+
|id |name  |city  |credit_score|credit_limit|id |name  |city  |credit_score|credit_limit|diffcolumn                        |
+---+------+------+------------+------------+---+------+------+------------+------------+----------------------------------+
|1  |gaurav|jaipur|550         |70000       |1  |gaurav|jaipur|550         |70000       |[, , , , ]                        |
|2  |sunil |noida |650         |90000       |2  |sunil |noida |600         |80000       |[, , , credit_score, credit_limit]|
+---+------+------+------------+------------+---+------+------+------------+------------+----------------------------------+

Но я Я не могу получить id и diffcolumn отдельно. Если я сделаю somedf.select ('id), это даст мне ошибку неоднозначности, потому что в объединенной таблице есть два идентификатора. Я хочу получить все имена столбцов в любом массиве и идентификатор, соответствующие значениям которых изменились. Как и в кредитном балле changeDF и кредитном лимите id = 2, name = sunil было изменено. Поэтому я хотел, чтобы результирующий фрейм данных дал мне результат, подобный

+--+---+------+------+------------+------------+---+
|id   | diffcolumn                        |         
+---+------+------+------------+------------+---
|2   |[, , , credit_score, credit_limit] |
+---+------+------+------------+------------+---+

Может кто-нибудь предложить мне, какой подход следует использовать, чтобы получить eh id и изменить столбец отдельно в фрейме данных.

Ответы [ 2 ]

0 голосов
/ 16 марта 2020

Просто измените условие соединения с col("a.id") === col("b.id") на "id"

Тогда будет только один столбец id.

Кроме того, вам не нужно alias("a") и alias("b"). Таким образом, ваше объединение упрощается с

changedDF.alias("a").join(originalDF.alias("b"), col("a.id") === col("b.id"))

до

changedDF.join(originalDF, "id")
0 голосов
/ 02 марта 2020

Попробуйте это:

    val aliasedChangedDF = changedDF.as("a")
    val aliasedOriginalDF = originalDF.as("b")
    val diff = udf((col: String, c1: String, c2: String) => if (c1 == c2) "" else col )
    val somedf=aliasedChangedDF.join(aliasedOriginalDF, col("a.id") === col("b.id")).withColumn("diffcolumn", split(concat_ws(",",changedDF.columns.map(x => diff(lit(x), changedDF(x), originalDF(x))):_*),","))
    somedf.select(col("a.id").as("id"),col("diffcolumn"))
...