考虑以下Dataframe:
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)
有据可查的是,删除重复项将导致此处的不确定性行为:
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
...
这样做的原因是 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
...
如果希望从特定列子集中选择不同的值,则 distinct
函数也存在,例如。 df.select('id','key').distinct()
.
然而,spark开发人员继续将与此相关的问题作为“预期行为”来解决,并忠实地将其添加到spark3api中。
所以。。。这是我真正的问题:
这个api函数崩溃了,在我能想象的任何情况下都会做错事。用于选择子集 distinct
是正确的使用方法,在所有其他情况下,使用 dropDuplicates
导致未定义的不确定性行为,这在数据处理工作负载中是非常不可取的。
我错过什么了吗?
在什么情况下使用它有用 dropDuplicates
?
暂无答案!
目前还没有任何答案,快来回答吧!