pyspark--中位数计算

本文介绍如何使用PySpark进行分组中位数和分位数的计算,包括基本的中位数计算、保留原始数据的中位数计算,以及不同比重的分位数计算方法。同时,也介绍了如何对单列数据进行分位数计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分组中位数计算

原始数据如下:

from pyspark.sql import Row
from pyspark.sql.window import Window
from pyspark.sql.functions import mean, col
from pyspark.sql import functions as F

col_names = ["name", "date", "score"]
value = [
    ("Ali", "2020-01-01", 10.0),
    ("Ali", "2020-01-02", 15.0),
    ("Ali", "2020-01-03", 20.0),
    ("Ali", "2020-01-04", 25.0),
    ("Ali", "2020-01-05", 30.0),
    ("Bob", "2020-01-01", 15.0),
    ("Bob", "2020-01-02", 20.0),
    ("Bob", "2020-01-03", 30.0)
]
df = spark.createDataFrame(value, col_names)

如果想要计算每个对象的中位数,可以用如下代码:

wind = Window.partitionBy('name')
med = F.expr('percentile_approx(score, 0.5)')
df.groupBy('name').agg(med.alias('med_val')).show()
+----+-------+
|name|med_val|
+----+-------+
| Bob|   20.0|
| Ali|   20.0|
+----+-------+

expr函数可以解析hive SQL函数,具体可参考文末链接。

假如不仅要计算每个人的中位数,还想保留原始数据,可以用如下代码:

df.withColumn('med_val', med.over(wind)).show()
+----+----------+-----+-------+
|name|      date|score|med_val|
+----+----------+-----+-------+
| Bob|2020-01-01| 15.0|   20.0|
| Bob|2020-01-02| 20.0|   20.0|
| Bob|2020-01-03| 30.0|   20.0|
| Ali|2020-01-01| 10.0|   20.0|
| Ali|2020-01-03| 20.0|   20.0|
| Ali|2020-01-04| 25.0|   20.0|
| Ali|2020-01-02| 15.0|   20.0|
| Ali|2020-01-05| 30.0|   20.0|
+----+----------+-----+-------+

拓展一下,如果想要计算不同比重的分位数,可以用如下代码:

med = F.expr('percentile_approx(score, array(0.25, 0.5, 0.75))')
df.withColumn('med_val', med.over(wind)).show()
+----+----------+-----+------------------+
|name|      date|score|           med_val|
+----+----------+-----+------------------+
| Bob|2020-01-01| 15.0|[15.0, 20.0, 30.0]|
| Bob|2020-01-02| 20.0|[15.0, 20.0, 30.0]|
| Bob|2020-01-03| 30.0|[15.0, 20.0, 30.0]|
| Ali|2020-01-02| 15.0|[15.0, 20.0, 25.0]|
| Ali|2020-01-05| 30.0|[15.0, 20.0, 25.0]|
| Ali|2020-01-01| 10.0|[15.0, 20.0, 25.0]|
| Ali|2020-01-03| 20.0|[15.0, 20.0, 25.0]|
| Ali|2020-01-04| 25.0|[15.0, 20.0, 25.0]|
+----+----------+-----+------------------+

单列分位数计算

有些情况下,需要单独对某一列数值做分析,可以采用dataframe的approxQuantile属性:

df.approxQuantile("score", [0.2,0.3,0.6,1.0], 0)

结果为:
[15.0, 15.0, 20.0, 30.0]

参考链接:

median-quantiles-within-pyspark-groupby

hive percentile和percentile_approx

PyCharm是一款集成开发环境(IDE),它可以帮助你在Python项目中整合Apache Spark等大数据处理框架。如果你想在PyCharm中使用Pandas DataFrame求取Spark数据集的中位数,通常的做法是首先将DataFrame转换成Spark DataFrame,然后通过Spark SQL或者Spark的统计函数计算。 以下是一个简单的步骤: 1. **导入所需库**: ```python from pyspark.sql import SparkSession ``` 2. **创建SparkSession**(如果你还没有创建过的话): ```python spark = SparkSession.builder.appName("MedianExample").getOrCreate() ``` 3. **加载数据到Spark DataFrame**: ```python df = spark.read.format("your_data_source").load("your_data_path") ``` 4. **转换数据到Pandas DataFrame(如果需要)**,因为Pandas有一个内置的`median()`函数可以计算中位数: ```python df_pandas = df.toPandas() median_value = df_pandas["your_column_name"].median() ``` 5. **但是,在Spark中直接操作DataFrame会触发实际的计算,不会像Pandas那样立即返回结果,你可以这样获取中位数**: ```python # 使用Spark SQL的表达式计算中位数 from pyspark.sql.functions import percentile_approx median_expression = percentile_approx(df.your_column_name, 0.5) result = df.stat.approxQuantile('your_column_name', [0.5], 0.05) # 返回近似中位数 ``` 注意,`approxQuantile()`函数用于近似计算,因为Spark数据分布通常很大,不可能对所有元素排序。记得替换`"your_column_name"`为你实际的数据列名。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值