我想知道在pyspark中是否可以使用QuantileDiscretizer
转换器来获得percentile_rank
的结果。
目的是为了避免在整个列上计算percent_rank
,因为这会生成以下错误:
WARN WindowExec: No Partition Defined for Window operation!
Moving all data to a single partition, this can cause serious performance degradation.
我采用的方法是首先使用 QuantileDiscretizer
,然后归一化到 [0,1]:
from pyspark.sql.window import Window
from pyspark.ml.feature import QuantileDiscretizer
from scipy.stats import gamma
X1 = gamma.rvs(0.2, size=1000)
df = spark.createDataFrame(pd.DataFrame(X1, columns=["x"]))
df = df.withColumn("perc_rank", F.percent_rank().over(Window.orderBy("x")))
df = QuantileDiscretizer(numBuckets=df.count()+1,\
inputCol="x",\
outputCol="q_discretizer").fit(df).transform(df)
agg_values = df.agg(F.max(df["q_discretizer"]).alias("maxval"),\
F.min(df["q_discretizer"]).alias("minval")).collect()[0]
xmax, xmin = agg_values.__getitem__("maxval"), agg_values.__getitem__("minval")
normalize = F.udf(lambda x: (x-xmin)/(xmax-xmin))
df = df.withColumn("perc_discretizer", normalize("q_discretizer"))
df = df.withColumn("error", F.round(F.abs(F.col("perc_discretizer")- F.col("perc_rank")),6) )
print(df.select(F.max("error")).show())
df.show(5)
然而,似乎增加数据点的数量会增加误差,所以我不确定这是否是正确的方法。
是否可以使用QuantileDiscretizer
来获取百分位数排名?
或者,是否有一种高效的方式可以计算整个列的percentile_rank
?
F.lit("some_val")
,可以设置一个分区索引。 - Galuoises