pyspark中的dropDuplicates有什么实际用途?

Dou*_*oug 5 apache-spark pyspark

考虑以下数据框:

from pyspark.sql import SparkSession, Window
from pyspark.sql.functions import row_number

import pandas as pd
import numpy as np

spark = SparkSession.builder.getOrCreate()

pdf = pd.DataFrame(np.random.random_integers(0, 10, size=[64, 2]), columns=['id', 'key'])
pdf['value'] = pdf['key'].apply(lambda v: 'value--%d' % v)
df = spark.createDataFrame(pdf)
Run Code Online (Sandbox Code Playgroud)

据可查,删除重复项将导致此处 不确定行为:

df.dropDuplicates(subset=['id']).orderBy('id').show()
+---+---+--------+
| id|key|   value|
+---+---+--------+
|  0|  3|value--3|
...

df.dropDuplicates(subset=['id']).orderBy('id').show()
+---+---+--------+
| id|key|   value|
+---+---+--------+
|  0|  0|value--0| <--- Picked some random row
...
Run Code Online (Sandbox Code Playgroud)

原因是分区时subset没有定义排序顺序。

要消除这种不确定性行为,您必须使用窗口函数:

sort_window = Window.partitionBy(['id']).orderBy(['key']) <-- Explicitly choose sort order in window
df.withColumn('rank', row_number().over(sort_window)).filter('rank == 1').drop('rank').orderBy('id').show()
+---+---+--------+
| id|key|   value|
+---+---+--------+
|  0|  0|value--0| <--- Always picks the same row
...
Run Code Online (Sandbox Code Playgroud)

如果您希望从特定列子集中选择不同的值,该distinct函数也存在,例如。df.select('id','key').distinct()

然而,Spark 开发人员继续将与此相关的问题视为“预期行为”,并忠实地将其添加到Spark 3 api中。

所以...这是我的实际问题:

这个糟糕的 API 函数似乎太糟糕了,在我能想象到的每种情况下它都会做错误的事情。选择子集distinct是正确的使用方法,而在所有其他情况下,使用会导致dropDuplicates未定义的非确定性行为,这在数据处理工作负载中是非常不希望的。

我错过了什么吗?

在什么情况下有用dropDuplicates