Как присвоить уникальный идентификатор каждому соответствующему уникальному значению столбца? - PullRequest
1 голос
/ 19 июня 2020

Представьте себе фрейм данных, как показано ниже:

+-------+--------+---------+---------+--------+-----------------+---+
|address|lastname|firstname|patientid|policyno|visitid          |id |
+-------+--------+---------+---------+--------+-----------------+---+
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_1| 1 |
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_2| 1 |
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_3| 1 |
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_1 | 2 |
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_2 | 2 |
|addr2  |Dobs    |OP       |patid3   |policy3 |visituid_OP_1    | 3 |
+-------+--------+---------+---------+--------+-----------------+---+

Значение столбца для «id» остается прежним, когда Имя (firstname + lastname) остается таким же, когда Имя становится другим - Я хочу назначить новый идентификатор.

Мне это нужно, потому что я хочу идентифицировать определенный набор данных (который содержит конфиденциальные данные), чтобы я мог использовать те же данные, но с измененными значениями, в моем приложении. Поле id будет использоваться как индексный ключ для соединения с другими фреймами данных.

Другая часть id состоит в том, что другие фиктивные фреймы данных также будут содержать аналогичный столбец id, который, вероятно, будет заполняется с помощью monotonically_increasing_id(), поэтому было бы лучше иметь id, начиная с 0 ИЛИ 1, непрерывно увеличиваясь.

Как я могу go достичь этого в искре с помощью scala ?

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Используйте функции window.

scala> df.show(false)
+-------+--------+---------+---------+--------+-----------------+
|address|lastname|firstname|patientid|policyno|visitid          |
+-------+--------+---------+---------+--------+-----------------+
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_1|
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_2|
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_3|
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_1 |
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_2 |
|addr2  |Dobs    |OP       |patid3   |policy3 |visituid_OP_1    |
|addr4  |AN      |OTHER    |patid4   |policy4 |visituid_OP_1    |
|addr2  |ANO     |THER     |patid5   |policy5 |visituid_OP_1    |
+-------+--------+---------+---------+--------+-----------------+
val expr = Seq("lastname","firstname")
            .map(c => hash(col(c)).as(c))
            .reduce(concat(_,_).asc)
val winSpec = dense_rank()
                .over(Window.orderBy(expr))

Вывод

scala> df.withColumn("id",winSpec).show(false)

+-------+--------+---------+---------+--------+-----------------+---+
|address|lastname|firstname|patientid|policyno|visitid          |id |
+-------+--------+---------+---------+--------+-----------------+---+
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_1|1  |
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_2|1  |
|addr1  |Pits    |Rodney   |patid1   |policy1 |visituid_rodney_3|1  |
|addr4  |AN      |OTHER    |patid4   |policy4 |visituid_OP_1    |2  |
|addr2  |Dobs    |OP       |patid3   |policy3 |visituid_OP_1    |3  |
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_1 |4  |
|addr2  |Dobs    |Aliya    |patid2   |policy2 |visituid_aliya_2 |4  |
|addr2  |ANO     |THER     |patid5   |policy5 |visituid_OP_1    |5  |
+-------+--------+---------+---------+--------+-----------------+---+

2 голосов
/ 19 июня 2020
import org.apache.spark.sql.functions._
val df = sc.parallelize(Seq(
  ("Xxx", "yyy"),
  ("xxx", "yyy"),
  ("aaa", "yyy")
)).toDF("c1", "c2")

df.withColumn("hashName", hash(concat($"c1", $"c2")))//.show(false)

Итак, какие очевидные улучшения? Символ-разделитель между обоими и прописными или строчными буквами перед ha sh. А если не очищено, замените все пробелы и нечетные символы разделителем.

Так что лучше:

df.withColumn("preHashName", lower(trim(concat($"c1", lit("|"), $"c2"))))
  .withColumn("hashName", hash(lower(concat($"c1", lit("|"), $"c2")))).show(false)

Если этого не сделать, значит, в другом ответе AN OTHER может быть таким же, как ANO THER с точки зрения хеширования.

Вывод:

+---+------+-----------+-----------+
|c1 |c2    |preHashName|hashName   |
+---+------+-----------+-----------+
|Xxx|y yy  |xxx|y yy   |907198499  |
|xxx|yyy   |xxx|yyy    |-1167597858|
|aaa|yyy   |aaa|yyy    |495090835  |
+---+------+-----------+-----------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...