pyspark 基于分位数的异常值剔除

先解释下四分位数

在这里插入图片描述

如何通过四分位数判断一组数据中的异常值

通过 Tukey’s Test方法计算,此方法可用于识别一组数据中的异常值:

具体方法如下:其中Q3代表上四分位数,Q1代表下四分位数,k代表系数,可以取值1.5或3。

  • 最大值估计= Q3+k(Q3-Q1)
  • 最小值估计= Q1-k(Q3-Q1)

当k=3时,代表极度异常值;
当k=1.5时,代表中度异常值。

代码实现

异常值:不属于正常的值 包含:缺失值,超过正常范围内的较大值或较小值
 + 分位数去极值
 + 中位数绝对偏差去极值
 + 正态分布去极值
上述三种操作的核心都是:通过原始数据设定一个正常的范围,超过此范围的就是一个异常值
# spark 分位数去极值
# https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.sql.DataFrame.approxQuantile.html?highlight=approxquantile
df = ss.createDataFrame([
    (1, 143.5, 651),
    (2, 509.9, 10),
    (3, 33.9, 1333),
    (4, 66.2, 904),
    (5, 133.2, 0),
    (6, 124.1, 10172),
    (7, 1.2, 1648093296)], ['id', 'cost', 'run_time'])
df.show()

cols = ['cost', 'run_time']

def quantile_excludes_outliers(df, cols, k_q1=1.5, k_q3=1.5):
    '''
    基于四分位剔除异常值
    :param df: spark dataframe
    :param cols: 列名列表
    :param k_q1: 下四分位系数
    :param k_q3: 上四分位系数
    :return: spark dataframe
    '''
    bounds = {}
    for col in cols:
        quantiles = df.approxQuantile(col,[0.25,0.75], 0.05)  # 返回下四分位数、上四分位
        IQR = quantiles[1] - quantiles[0]
        bounds[col] = [quantiles[0] - k_q1 * IQR, quantiles[1] + k_q3 * IQR]  # 最小值估计、最大值估计

    print(bounds)

    filter_quantile = fn.udf(lambda x, y: 'yes' if x < bounds[y][0] or x > bounds[y][1] else 'no')
    for c in cols:
        df = df.withColumn(c + '_is_outlier', filter_quantile(fn.col(c), fn.lit(c)))
        df = df.filter(df[c + '_is_outlier'] == 'no')

    df.show()
    
    df = df.drop(*[c + '_is_outlier' for c in cols])

    df.show()
    
    return df

quantile_excludes_outliers(df, cols, k_q1=1.5, k_q3=1.5)

+---+-----+----------+
| id| cost|  run_time|
+---+-----+----------+
|  1|143.5|       651|
|  2|509.9|        10|
|  3| 33.9|      1333|
|  4| 66.2|       904|
|  5|133.2|         0|
|  6|124.1|     10172|
|  7|  1.2|1648093296|
+---+-----+----------+

{'cost': [-130.49999999999997, 307.9], 'run_time': [-15233.0, 25415.0]}
+---+-----+--------+---------------+-------------------+
| id| cost|run_time|cost_is_outlier|run_time_is_outlier|
+---+-----+--------+---------------+-------------------+
|  1|143.5|     651|             no|                 no|
|  3| 33.9|    1333|             no|                 no|
|  4| 66.2|     904|             no|                 no|
|  5|133.2|       0|             no|                 no|
|  6|124.1|   10172|             no|                 no|
+---+-----+--------+---------------+-------------------+

+---+-----+--------+
| id| cost|run_time|
+---+-----+--------+
|  1|143.5|     651|
|  3| 33.9|    1333|
|  4| 66.2|     904|
|  5|133.2|       0|
|  6|124.1|   10172|
+---+-----+--------+

参考自:

https://blog.csdn.net/qq_30031221/article/details/109180961

https://zhuanlan.zhihu.com/p/344502263

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WGS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值