python处理异常值--箱型图查找异常值并替换

箱型图查找异常值并替换

	定义为值大于上四分位或者小于下四分位的值位异常值,若是异常值,则用mean替换,项目中遇到的,但是这个可能或将0值也替换了,但是0值不是异常值,故而舍弃这种方法。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats

'''
异常值分析
'''

# 加载数据

def get_data(df, row):
    # 截取第一列的数据
    df = df.iloc[:, 1]
    # 返回的是一个series,获取第一个序列
    '''
    1   {} 
    2   {}
    .
    .
    .
    10  {}
    '''
    series_1 = df[row]
    # 返回的序列用逗号将其split,返回的是list类型,每个元素都是str,要将其转换成float,方便后边计算上下四分位
    list_1 = series_1.split(',')
    # 返回的是list类型,每个元素都是str,要将其转换成float,方便后边计算上下四分位
    for i in range(len(list_1)):
        list_1[i] = float(list_1[i])

    # 将list转换成series,因为box_plot_outliers接受的参数是series类型
    series = pd.Series(list_1)
    print(series)
    return series


def box_plot_outliers(data_ser, box_scale):
    '''
    利用箱型图去除异常值
    :param data_ser: 接收pandas.Series数据格式
    :param box_scale: 箱型图尺寸,取3
    :return:
    '''
    print(box_scale)
    print(type(box_scale))
    s = (data_ser.quantile(0.75) - data_ser.quantile(0.25))
    print(s)
    print(type(s))
    iqr = box_scale * (data_ser.quantile(0.75) - data_ser.quantile(0.25))
    # 下阈值
    val_low = data_ser.quantile(0.25) - iqr * 0.5
    # 上阈值
    val_up = data_ser.quantile(0.25) + iqr * 0.5
    # 异常值
    outlier = data_ser[(data_ser < val_low) | (data_ser > val_up)]
    # 正常值
    normal_val = data_ser[(data_ser > val_low) & (data_ser < val_up)]
    return outlier, normal_val, val_low, val_up


if __name__ == '__main__':
    df = pd.read_csv(
        r'C:\Users\yelinfeng\Downloads\photovoltaics-master\photovoltaics-master\test.csv')
    series = get_data(df, 2)
    outlier, normal_val, val_low, val_up = box_plot_outliers(series, 3)
    print('异常值:' + str(outlier))
    outlier = np.array(outlier)
    print('val_up的类型:{}'.format(type(val_up)))
    print('normal_val的类型:{}'.format(type(normal_val)))
    print(normal_val)
    sum = 0  # 累加非异常值的数
    normal_val = np.array(normal_val)
    for i in range(len(normal_val)):
        sum += normal_val[i]
    # 刨除异常值后的均值,因为异常值可能对均值的影响很大
    mean = sum / (len(normal_val))
    print('均值:{}'.format(mean))
    if outlier is None:
        print('没有异常值')
    else:
        for i, val in enumerate(series):
            # 比如【pandas.mean()求平均值后是一个<class 'numpy.float64'>类型】转换成Python的float类型numpy.float(value)
            val_up = np.float(val_up)
            val_low = np.float(val_low)
            # 比较大小,如果在大于上四分位或者小于下四分位,则将其替换为位mean,如果不是则采用真实值val
            series[i] = float(np.where((((val < val_low) | (val > val_up))), mean, val))
    print(series)
    print(series[35])

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值