apache-spark - PySpark groupBy 中的中位数/分位数

标签 apache-spark pyspark apache-spark-sql pyspark-sql

我想在 Spark 数据帧上计算组分位数(使用 PySpark)。近似或精确的结果都可以。我更喜欢可以在 groupBy 的上下文中使用的解决方案/agg ,以便我可以将它与其他 PySpark 聚合函数混合使用。如果由于某种原因这是不可能的,另一种方法也可以。

This question相关但不说明如何使用 approxQuantile作为聚合函数。

我也可以访问 percentile_approx Hive UDF 但我不知道如何将其用作聚合函数。

为了具体起见,假设我有以下数据框:

from pyspark import SparkContext
import pyspark.sql.functions as f

sc = SparkContext()    

df = sc.parallelize([
    ['A', 1],
    ['A', 2],
    ['A', 3],
    ['B', 4],
    ['B', 5],
    ['B', 6],
]).toDF(('grp', 'val'))

df_grp = df.groupBy('grp').agg(f.magic_percentile('val', 0.5).alias('med_val'))
df_grp.show()

预期结果是:
+----+-------+
| grp|med_val|
+----+-------+
|   A|      2|
|   B|      5|
+----+-------+

最佳答案

我想你不再需要它了。但是会把它留在这里给后代(即下周我忘记的时候)。

from pyspark.sql import Window
import pyspark.sql.functions as F

grp_window = Window.partitionBy('grp')
magic_percentile = F.expr('percentile_approx(val, 0.5)')

df.withColumn('med_val', magic_percentile.over(grp_window))
或者为了准确解决您的问题,这也有效:
df.groupBy('grp').agg(magic_percentile.alias('med_val'))
作为奖励,您可以传递一组百分位数:
quantiles = F.expr('percentile_approx(val, array(0.25, 0.5, 0.75))')
你会得到一个列表作为返回。

关于apache-spark - PySpark groupBy 中的中位数/分位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46845672/

相关文章:

java - Spark 流 : Different average values returned by PairDStream. 打印

apache-spark - Spark : Replace missing values with values from another column

python - pickle Spark RDD 并将其读入 Python

python - pyspark - 多个输入文件到一个 RDD 和一个输出文件

pyspark - 将列表列拆分为同一 PySpark 数据框中的多列

java - 如何使用套接字实现 Spark 流式输出

java - 如何在Spark 1.3.1中使用Java读取AVRO数据?

apache-spark - Spark DataFrames 中的 argmax : how to retrieve the row with the maximum value

scala - 在 Spark 中使用 groupBy 并返回到 DataFrame

python - 为什么 pyspark 在 macOS 上给出 "we couldn' t find any external IP address?