Получить идентификаторы для повторяющихся строк (с учетом всех других столбцов) в Apache Spark
у меня есть фрейм данных sql Spark, состоящий из и n
столбцы "данные", т. е.
id | dat1 | dat2 | ... | datn
на id
columnn однозначно определяется, тогда как, глядя на dat1 ... datn
там могут быть дубликаты.
моя цель-найти id
s этих дубликатов.
мой подход до сих пор:
-
получить дубликаты строк с помощью
groupBy
:dup_df = df.groupBy(df.columns[1:]).count().filter('count > 1')
-
Регистрация the
dup_df
Сdf
чтобы получить дубликаты строк в том числеid
:df.join(dup_df, df.columns[1:])
Я совершенно уверен, что это в основном правильно, это не удается, потому что dat1 ... datn
столбцы содержат null
значения.
сделать join
on null
значения, я нашел .е.г это так пост. Но для этого потребуется построить огромное "условие соединения строк".
- есть ли простой / более общий / более питонический способ сделать
joins
onnull
значения? - или, еще лучше, есть другой (проще, красивее,...) метод получения желаемого
id
s?
BTW: я использую Spark 2.1.0 и Python 3.5.3
1 ответов
если количество ids
в группе относительно невелико, вы можете groupBy
и collect_list
. Необходимый импорт
from pyspark.sql.functions import collect_list, size
пример:
df = sc.parallelize([
(1, "a", "b", 3),
(2, None, "f", None),
(3, "g", "h", 4),
(4, None, "f", None),
(5, "a", "b", 3)
]).toDF(["id"])
запрос:
(df
.groupBy(df.columns[1:])
.agg(collect_list("id").alias("ids"))
.where(size("ids") > 1))
и в итоге:
+----+---+----+------+
| _2| _3| _4| ids|
+----+---+----+------+
|null| f|null|[2, 4]|
| a| b| 3|[1, 5]|
+----+---+----+------+
вы можете подать заявку explode
дважды (или используйте udf
) в выходной эквивалентен вернулся из join
.
вы также можете идентифицировать группы, используя minimal id
в группе. Несколько дополнительных импорт:
from pyspark.sql.window import Window
from pyspark.sql.functions import col, count, min
окне определение:
w = Window.partitionBy(df.columns[1:])
запрос:
(df
.select(
"*",
count("*").over(w).alias("_cnt"),
min("id").over(w).alias("group"))
.where(col("_cnt") > 1))
и в итоге:
+---+----+---+----+----+-----+
| id| _2| _3| _4|_cnt|group|
+---+----+---+----+----+-----+
| 2|null| f|null| 2| 2|
| 4|null| f|null| 2| 2|
| 1| a| b| 3| 2| 1|
| 5| a| b| 3| 2| 1|
+---+----+---+----+----+-----+
вы можете использовать group
столбец для самостоятельного соединения.