[Python] 数据预处理(缺失值、异常值、重复值) [相关方法参数说明、代码示例、相关概念](三)

简介: [Python] 数据预处理(缺失值、异常值、重复值) [相关方法参数说明、代码示例、相关概念](三)

1.2.3 使用平均值填补缺失值

调用 fillna() 方法,使用每列的平均值对数据表中对应列的缺失值进行填补。

  • mean():
  • 获取调用该方法的数据集的一行或一列的平均值。
  • axis:轴向,默认 axis=0 计算每列的算数平均数,axis=1 计算每行的算数平均数。

经过验证,调用 mean() 方法计算列的均值,空值(缺失值)不会计算在内。

# 包的导入
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_excel('../../监测点C逐小时污染物浓度与气象实测数据.xlsx')
# 由于表格中的部分缺失值使用字符串类型的'—' 'NULL' 'NA' 表示
# 所有先对这些数据进行处理
def fun(x):
  if (x=='—' or x=='NULL' or x=='NA'): return np.nan
  else: return x
# applymap() 方法会遍历并处理表格中每个单元格的数据
# fun 为传入的函数参数,用于处理每个单元格
# fun 函数会接收一个参数,为表格中每个单元格的数据
data = data.applymap(fun)
# 使用每列的均值对每列中的缺失值进行填补
# def fun_mean(col):
#   如果当前列是第二列直接退出函数
#   第二列的数据为字符串类型
#   if (col.name == '地点'): return col
#   col.fillna(value=col.mean(), inplace=True)
#   return col
# re = data.apply(fun_mean)
# 循环处理第三列及往后的每列
# 使用每列的均值对每列中的缺失值进行填补
for col_name in data.columns[2:]:
  # 当前要处理的列
  col = data[col_name]
  # 使用当前列的均值填补缺失值
  col.fillna(value=col.mean(), inplace=True)
  # 更新原数据表
  data[col_name] = col
data

返回文章目录

1.2.4 使用众数填补缺失值

调用 fillna() 方法,使用每列的众数对数据表中对应列的缺失值进行填补。

  • mode():
  • 获取调用该方法的数据集的一行或一列的众数。如果个数最多的取值存在多个,则返回多个值。
  • axis:轴向,默认 axis=0 获取每列的众数,axis=1 获取每行的众数。

湿度这一列的取值情况如下:

# 包的导入
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_excel('../../监测点C逐小时污染物浓度与气象实测数据.xlsx')
# 由于表格中的部分缺失值使用字符串类型的'—' 'NULL' 'NA' 表示
# 所有先对这些数据进行处理
def fun(x):
  if (x=='—' or x=='NULL' or x=='NA'): return np.nan
  else: return x
# applymap() 方法会遍历并处理表格中每个单元格的数据
# fun 为传入的函数参数,用于处理每个单元格
# fun 函数会接收一个参数,为表格中每个单元格的数据
data = data.applymap(fun)
# 使用每列的众数对每列中的缺失值进行填补
def fun_(col):
  # 获取第一个众数填补缺失值
  col.fillna(value=col.mode()[0], inplace=True)
  return col
re = data.apply(fun_)
re

返回文章目录

1.2.5 使用中位数填补缺失值

调用 fillna() 方法,使用每列的中位数对数据表中对应列的缺失值进行填补。

  • median():
  • 获取调用该方法的数据集的一行或一列的中位数。
  • axis:轴向,默认 axis=0 获取每列的中位数,axis=1 获取每行的中位数。

湿度这一列的中位数如下:

# 包的导入
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_excel('../../监测点C逐小时污染物浓度与气象实测数据.xlsx')
# 由于表格中的部分缺失值使用字符串类型的'—' 'NULL' 'NA' 表示
# 所有先对这些数据进行处理
def fun(x):
  if (x=='—' or x=='NULL' or x=='NA'): return np.nan
  else: return x
# applymap() 方法会遍历并处理表格中每个单元格的数据
# fun 为传入的函数参数,用于处理每个单元格
# fun 函数会接收一个参数,为表格中每个单元格的数据
data = data.applymap(fun)
# 使用每列的中位数对每列中的缺失值进行填补
def fun_(col):
  # 如果当前列是第二列直接退出函数
  # 第二列的数据为字符串类型
  if (col.name == '地点'): return col
  col.fillna(value=col.median(), inplace=True)
  return col
re = data.apply(fun_)
re

返回文章目录

1.2.6 使用缺失值前一个与后一个非缺失值的均值填补

调用 interpolate() 方法,使用每列的缺失值前一个与后一个非缺失值的均值对数据表中对应列的缺失值进行填补。

如果第一行就存在缺失值,则本方法不适用,缺失值不会被填补,仍然为 NaN。

当前的测试数据如下:

# 包的导入
import pandas as pd
import numpy as np
# 读取数据
data = pd.read_excel('../../1.xlsx')
# 由于表格中的部分缺失值使用字符串类型的'—' 'NULL' 'NA' 表示
# 所有先对这些数据进行处理
def fun(x):
  if (x=='—' or x=='NULL' or x=='NA'): return np.nan
  else: return x
# applymap() 方法会遍历并处理表格中每个单元格的数据
# fun 为传入的函数参数,用于处理每个单元格
# fun 函数会接收一个参数,为表格中每个单元格的数据
data = data.applymap(fun)
# 使用每列的缺失值前一个与后一个非缺失值的均值
# 对每列中的缺失值进行填补
def fun_(col):
  # 第一列为时间类型直接退出函数
  if (col.name == '实测日期'): return col
  # 如果当前列是第二列直接退出函数
  # 第二列的数据为字符串类型
  if (col.name == '地点'): return col
  # col = col.interpolate()
  # 直接修改原数据
  col.interpolate(inplace=True)
  return col
re = data.apply(fun_)
re

返回文章目录

1.2.7 使用拉格朗日插值法对缺失值进行填补

以下内容来自:

[1]赵莉,孙娜,李丽萍,崔杰.拉格朗日插值法在数据清洗中的应用[J].辽宁工业大学学报(自然科学版),2022,42(02):102-105+117.DOI:10.15916/j.issn1674-3261.2022.02.007.

文献知网连接

返回文章目录

1.2.7.1 拉格朗日插值法

拉格朗日多项式插值法的基本思想是:给出一个恰好穿过二维平面上几个已知点的多项式,利用最小次数的多项式来构建一条光滑曲线,使曲线通

过所有已知点。


image.png

image.png

image.png

将 x=18 代入可以得到 L(18)=-11,因此缺失的值是-11。

返回文章目录

1.2.7.2 代码

当前将要进行缺失值填补的数据:

为了防止取缺失值前后的非缺失值时索引越界,对文献中的代码进行了修改

import numpy as np
import pandas as pd
# 引入拉格朗日插值法所需的方法
from scipy.interpolate import lagrange
# 文件读取
data = pd.read_excel('../../1.xlsx')
# 字符串表示的空值预处理
def fun(x):
  if (x=='—' or x=='NULL' or x=='NA'): return np.nan
  else: return x
data = data.applymap(fun)
# 生成拉格朗日插值
def interpolate_columns(data_col, missing_val_idx, k=5):
  """
  data_col: 需要进行缺失值填补的列
  missing_val_idx: 数据缺失的单元格在该列对应的索引
  k: 缺失值前后取值的个数, 默认为5个
  return: 返回拉格朗日插值
  """
  # 防止取缺失值前后的非缺失值时下标越界
  # 向缺失值前取值的个数,默认为 k
  f_k = k
  # 如果缺失值前还有的数值个数小于 k
  # 更改取值个数
  if(missing_val_idx < k): f_k = missing_val_idx
  # 向缺失值后取值的个数,默认为 k
  b_k = k
  # 如果缺失值后还有的数值个数小于 k
  # 更改取值个数
  if((data_col.size-missing_val_idx-1) < k): b_k = data_col.size-missing_val_idx-1
  # 获取二者的较小值
  if(f_k <= b_k): k = f_k
  else: k = b_k
  # 取出当前缺失值位置前后 k 个值
  y = data_col[ 
    list(range(missing_val_idx-k, missing_val_idx))  + list(range(missing_val_idx+1, missing_val_idx+1+k)) 
  ]
  # 去除空值
  y = y[ y.notnull() ]
  # 生成拉格朗日插值函数
  f = lagrange(y.index, list(y))
  # 计算并返回缺失值将要填补的数据值
  return f(missing_val_idx)
# 遍历数据表
# 每列
for i in data.columns[2:]:
  # 遍历每列中的每个单元格
  for j in range(data[i].size):
    # 如果单元格为空
    # 进行拉格朗日插值
    if data[i].isnull()[j]:
      data[i][j] = interpolate_columns(data[i], j)
data

此代码无法对数据表第一行与最后一行存在的缺失值进行填补,由于代码修改,当缺失值在第一行或最后一行时,取缺失值前后的非缺失值的个数为0,所以无法使用拉格朗日插值法进行数据的填补。

文献中的代码:

返回文章目录

1.2.8 使用预测模型对缺失值进行填补

预测模型较多,后面补上

返回文章目录

2. 异常值处理

返回文章目录

2.1 异常值的检测

  • 检查数据集中的异常值,常用的方法有:
  • 3σ 准则(拉依达准则)
  • 箱线图检测

返回文章目录

2.1.1 3σ 准则(拉依达准则)

相关概念

3σ(西格玛)准则(拉依达准则) 是指先假设一组检测数据只含有随机误差,对其进行计算处理得到标准偏差,按一定概率确定一个区间,认为凡超过这个区间的误差,就不属于随机误差而是粗大误差,含有该误差的数据应予以剔除。

这种判别处理原理及方法 仅局限于对正态或近似正态分布 的样本数据处理,它是 以测量次数充分大为前提 的,当测量次数少的情形用准则剔除粗大误差是不够可靠的。因此,在测量次数较少的情况下,最好不要选用该准则

来源于百度百科 链接

在正态分布中:

符号 说明
μ  数学期望(均值)
σ 2  方差
σ  标准差

image.png


“小概率事件”和假设检验的基本思想:“小概率事件” 通常指发生的概率小于5% 的事件,认为在一次试验中该事件是 几乎不可能发生 的。由此可见 X落在(μ-3σ,μ+3σ)以外 的概率小于千分之三,在实际问题中常认为相应的事件 不会发生 ,基本上可以把区间(μ-3σ,μ+3σ)看作是随机变量X实际可能的取值区间,这称之为正态分布的“3σ”原则

来源于百度百科 链接


image.png

image.png


在整理试验数据时,往往会遇到这样的情况,即在一组试验数据里,发现少数几个偏差特别大的可疑数据,这类数据称为 Outlier 或 Exceptional Data ,他们往往是由于过失误差引起。

来源于百度百科 链接

数据分布图绘制
  • seaborn.distplot():
  • 参数:
  • a:接收一维数组或列表为参数,为绘制图形的数据。
  • hist:是否显示直方图,默认值为 True,默认情况下显示直方图。
  • kde:是否显示核密度估计,默认值为 True,默认情况下显示核密度估计。
  • bins:接收 int 或 list 类型的数据为参数,控制直方图的划分,即直方图有几柱。
  • rug:是否绘制变量的分布情况,默认值为 False,默认情况下不显示。
  • fit:
  • hist_kws:接收字典类型的数据为参数,设置绘制的直方图的显示样式。
  • kde_kws:接收字典类型的数据为参数,设置绘制的核密度估计的显示样式。
  • rug_kws:接收字典类型的数据为参数,设置绘制的变量分布情况的显示样式。
  • color:设置绘制图形的颜色。
  • vertical:绘制的图形x轴与y轴是否进行对调,绘制的图形显示在x轴还是y轴,默认值为False,显示在x轴。
  • norm_hist:控制直方图的高度(y轴)显示的是密度还是计数。在不含有核密度估计的图形中,默认为 False,显示的为计数。在含有核密度估计的图形中,默认为 True,显示的为密度。
  • axlabel:接收字符串类型的数据为参数,用于设置x轴的标签。
  • label:接收字符串类型的数据为参数,用于设置直方图的图例。
  • ax:seaborn.distplot() 会返回一个坐标轴对象,可以用于设置图形的四个坐标轴。

参考:

【Python可视化 | Seaborn之seaborn.distplot()】鹿港小小镇

【sns.distplot()用法】小小喽啰

数据文件名:

监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_补全数据_去除负数.xlsx

这里只进行简单的测试,更加详细的测试【待写】

绘制 SO2监测浓度 的数据分布图

import pandas as pd
# 画图所需的包
import matplotlib.pyplot as plt
# 绘制数据分布图所需的包
import seaborn as sns
# 提高 matplotlib 在 jupyter 中作图的分辨率
%config InlineBackend.figure_format = 'retina'
# 处理中文与负号的显示问题
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
data = pd.read_excel('./监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_补全数据_去除负数.xlsx')
# 修改列名
data.columns = ['监测时间', '地点', 'SO2监测浓度', 'NO2监测浓度', 'PM10监测浓度',
       'PM2.5监测浓度', 'O3监测浓度', 'CO监测浓度', '温度', '湿度',
       '气压', '风速', '风向']
# 绘制数据分布图
# ax 接收返回的坐标轴对象
ax = sns.distplot(
  # 绘制图形的数据
  data['SO2监测浓度'],
  # 直方图柱 20个 
  bins=20, 
  # 显示变量的分布情况
  rug=True,
  # 直方图样式设置
  hist_kws={
    'label': 'SO2监测浓度',
    'color': 'red'
  },
  # 核密度估计曲线样式设置
  kde_kws={
    'label': 'SO2监测浓度核密度估计',
    'color': 'green'
  },
  # 设置x轴的标签
  axlabel= r'$SO_{2}$'
)
# 取消上轴和右轴的显示
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
# 显示图例
plt.legend()
plt.show()

返回文章目录

2.1.2 箱线图检测

以下内容来自:

[1]孙向东,刘拥军,陈雯雯,贾智宁,黄保续.箱线图法在动物卫生数据异常值检验中的运用[J].中国动物检疫,2010,27(07):66-68.

知网文献链接

相关概念

箱线图(Boxplot)也称箱须图(Box-whisker Plot),是美国著名统计学家 John W. Tukey 于 1977 年发明的。箱线图法利用数据中的五个统计量:最小值、下四分位数(Q1)、中位数(Q2)、上四分位数(Q3)与最大值 来描述数据。

  • 箱线图可用于:
  • (1)鉴别数据中的异常值,包括离群值和极端值;
  • (2) 判断数据的偏态和尾重;
  • (3)比较几组数据的形状。

以下内容(本文)仅讨论其在异常值鉴别中的应用。

箱线图根据实际数据绘制,既 不需要事先假定数据服从特定的概率分布 ,也 没有对数据作任何限制性要求 ,能够真实、直观地表现数据形状的本来面貌。

箱线图判断异常值的标准以四分位数和四分位距为基础,较多数据的变化对四分位数影响不大,所以箱线图判断异常值的标准具有较强的鲁棒性(Robust),检测结果比较客观。

箱线图法采用中位数代替平均数检测异常值是统计检测方法上的一大改进。箱线图法能够有效克服数据中存在异常值时,不能测出异常值的这种掩盖效应(masking effect)。

箱线图的结构:

箱线图由参照系(坐标轴)、标志物(箱体、上下四分位线、中位线、异常值截断点)、检测数据(箱体两端的延伸线、异常值)三种成分构成,具体

见图1。

其中 箱体的两端分别对应下四分位数 Q1 和上四分位数 Q3Q1和 Q3之间称作四分位距 (Inter Quartile Range,IQR)。 上四分位点右边 1.5倍 IQR 和下四分位点左边 1.5 倍 IQR位置对应的点是异常值截断点 ,异常值截断点之间是内限。上四分位点右边 3 倍 IQR 和下四分位点左边 3 倍IQR 位置对应的点是极端值截断点,极端值截断点之间是外限。

异常值截断点以外的数据称作异常值 ,其中在内限与外限之间的异常值为温和异常值或离群值(Outlier,mild outliers),在外限以外的为极端异常值或极端值(Extreme,extreme outliers)。

箱线图的结构与标准正态分布函数 N(0, 1) 之间的比较见图2。

其中 Q3 与 Q1 之间包含了 50%的数据点,异常值截断点之间包含了 99.3%的数据点,非异常值误判为异常值的概率不大于 0.7%。

箱线图的结构图

箱线图绘制

以下博客对于绘制箱线图的方法参数介绍的很详细,这里不在进行介绍。

  • matplotlib.pyplot.boxplot()
将方法的参数及其说明复制在这:
x:指定要绘制箱线图的数据,可以是一组数据也可以是多组数据;
notch:是否以凹口的形式展现箱线图,默认非凹口;
sym:指定异常点的形状,默认为蓝色的+号显示;
vert:是否需要将箱线图垂直摆放,默认垂直摆放;
whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差;
positions:指定箱线图的位置,默认为range(1, N+1),N为箱线图的数量;
widths:指定箱线图的宽度,默认为0.5;
patch_artist:是否填充箱体的颜色,默认为False;
meanline:是否用线的形式表示均值,默认用点来表示;
showmeans:是否显示均值,默认不显示;
showcaps:是否显示箱线图顶端和末端的两条线,默认显示;
showbox:是否显示箱线图的箱体,默认显示;
showfliers:是否显示异常值,默认显示;
boxprops:设置箱体的属性,如边框色,填充色等;
labels:为箱线图添加标签,类似于图例的作用;即箱线图对应x轴点的名字
flierprops:设置异常值的属性,如异常点的形状、大小、填充色等;
medianprops:设置中位数的属性,如线的类型、粗细等;
meanprops:设置均值的属性,如点的大小、颜色等;
capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等;
whiskerprops:设置须的属性,如颜色、粗细、线的类型等;
manage_ticks:是否自适应标签位置,默认为True;
autorange:是否自动调整范围,默认为False;
  • seaborn.boxplot()
将方法的参数及其说明复制在这:
x, y, hue:数据或向量数据中的变量名称
用于绘制长格式数据的输入。
data:DataFrame,数组,数组列表
用于绘图的数据集。
如果x和y都缺失,那么数据将被视为宽格式。
否则数据被视为长格式。
order, hue_order:字符串列表
控制分类变量(对应的条形图)的绘制顺序,
若缺失则从数据中推断分类变量的顺序。
orient:“v”或“h”
控制绘图的方向(垂直或水平)。
这通常是从输入变量的 dtype 推断出来的,
但是当“分类”变量为数值型或绘制宽格式数据时
可用于指定绘图的方向。
color:matplotlib颜色
所有元素的颜色,或渐变调色板的种子颜色。
palette:调色板名称,列表或字典
用于hue变量的不同级别的颜色。
可以从color_palette()得到一些解释,
或者将色调级别映射到matplotlib颜色的字典。
saturation:float
控制用于绘制颜色的原始饱和度的比例。
通常大幅填充在轻微不饱和的颜色下看起来更好,
如果您希望绘图颜色与输入颜色规格完美匹配
可将其设置为1。
width:float
不使用色调嵌套时完整元素的宽度,
或主要分组变量一个级别的所有元素的宽度。
dodge:bool
使用色调嵌套时,元素是否应沿分类轴移动。
fliersize:float
用于表示异常值观察的标记的大小。
linewidth:float
构图元素的灰线宽度。
whis:float
控制在超过高低四分位数时 IQR (四分位间距)的比例,
因此需要延长绘制的触须线段。超出此范围的点将被识别为异常值。
notch:boolean
是否使矩形框“凹陷”以指示中位数的置信区间。
还可以通过plt.boxplot的一些参数来控制
ax:matplotlib轴
绘图时使用的 Axes 轴对象,否则使用当前 Axes 轴对象
kwargs:键值映射
其他在绘图时传给plt.boxplot的参数
设置方法与 plt.boxplot 一样

数据文件名:

监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_补全数据_去除负数.xlsx

绘制 SO2监测浓度 的箱线图

测试一些经常会使用的参数和参数的常用设置

matplotlib.pyplot.boxplot()

import pandas as pd
# 画图所需的包
import matplotlib.pyplot as plt
# 提高 matplotlib 在 jupyter 中作图的分辨率
%config InlineBackend.figure_format = 'retina'
# 处理中文与负号的显示问题
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
data = pd.read_excel('./监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_补全数据_去除负数.xlsx')
# 修改列名
data.columns = ['监测时间', '地点', 'SO2监测浓度', 'NO2监测浓度', 'PM10监测浓度',
       'PM2.5监测浓度', 'O3监测浓度', 'CO监测浓度', '温度', '湿度',
       '气压', '风速', '风向']
# 绘制箱线图
plt.boxplot(
  # 绘图数据
  data['SO2监测浓度'],
  # 箱子是否内凹
  # notch=True,
  # 设置异常点的形状
  # sym='.',
  # 填充箱体颜色
  patch_artist=True,
  # 显示平均值,默认使用点显示
  showmeans=True,
  # 设置箱子的宽度
  widths=0.1,
  # 设置箱子的样式,需要 patch_artist=True
  boxprops={
    # 箱子的边框为灰色
    'color': 'gray',
    # 箱子的填充色为橙色
    'facecolor': 'orange',
    # 设置边框线的宽度
    'linewidth': '2'
  },
  # 设置异常值点的样式
  flierprops={
    # 设置点的形状
    'marker': '.',
    # 设置点的填充色
    'markerfacecolor': 'blue',
    # 设置点的边框色
    'markeredgecolor': 'blue',
    # 设置点的大小
    'markersize': '2'
  },
  # 添加箱线图在x轴对应位置的名字
  # x轴坐标点名
  labels=['SO2监测浓度'],
  # 设置须的样式
  whiskerprops={
    # 设置线的颜色
    'color': 'green'
  },
  # 设置箱线图最值线的样式
  capprops={
    # 设置线的颜色
    'color': 'red',
    # 设置线的宽度
    'linewidth': '3'
  }
)
plt.grid(linestyle=':')
# 显示图例
plt.legend()
plt.show()

绘制 所有列 的箱线图

测试一些经常会使用的参数和参数的常用设置

seaborn.boxplot()

import pandas as pd
# 画图所需的包
import matplotlib.pyplot as plt
# 绘制数据分布图所需的包
import seaborn as sns
# 提高 matplotlib 在 jupyter 中作图的分辨率
%config InlineBackend.figure_format = 'retina'
# 处理中文与负号的显示问题
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
data = pd.read_excel('./监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_补全数据_去除负数.xlsx')
# 修改列名
data.columns = ['监测时间', '地点', 'SO2监测浓度', 'NO2监测浓度', 'PM10监测浓度',
       'PM2.5监测浓度', 'O3监测浓度', 'CO监测浓度', '温度', '湿度',
       '气压', '风速', '风向']
# 设置画布大小
plt.figure(figsize=(18, 5))
# 绘制箱线图
# 会返回一个坐标轴对象
ax = sns.boxplot(
  # x = data['NO2监测浓度'],
  # 绘图的数据
  # y = data['SO2监测浓度'],
  # 传入 DataFrame 类型的数据,会绘制每列的箱线图
  data=data,
  # 箱子的填充色
  # 有多个箱子,多个箱子的颜色都会一致
  # color='red',
  # 设置调色板,会根据调色板的颜色映射规则对箱子填充颜色
  palette='viridis',
  # 设置箱子的宽度
  width=0.7,
  # 异常值点的大小
  fliersize=2,
  # 箱线图中边框、线的宽度
  linewidth=1.2,
  # 箱子内凹
  notch=True,
  # 其他样式设置, 与 matplotlib.pyplot.boxplot() 一样
  # 显示均值
  showmeans=True,
  # 设置异常值点的样式
  flierprops={
    # 设置点的形状
    'marker': '.',
    # 设置点的填充色
    'markerfacecolor': 'blue',
    # 设置点的边框色
    'markeredgecolor': 'blue',
    # 设置点的大小
    'markersize': '2'
  }
)
# 取消上轴和右轴的显示
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('none')
plt.grid(linestyle=':')
# 显示图例
plt.legend()
plt.show()

返回文章目录

2.2 异常值的处理

  • 需要进行异常值处理的情况,主要有如下几种:
  • 1.数值的取值范围有明确的要求,对于不在要求的取值范围内的数据可以进行异常值的处理。如,要求取值要为正数,对于取值为负数的数值需要进行处理。
  • 2.使用 3σ 准则(拉依达准则)检测异常值,对于落在(μ-3σ,μ+3σ)以外的数据需要进行异常值处理。
  • 3.使用箱线图检测异常值,对于落在异常值截断线以外的数据需要进行异常值处理。
  • 异常值处理的方式:
  • 1.直接将异常值删除。
  • 2.将异常值置为空,采用缺失值填补的方法对异常值进行替换。

返回文章目录

2.2.1 对不在指定取值范围内的异常值处理

数据文件名:

监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_数据填补.xlsx

data['SO2监测浓度(μg/m³)'].value_counts

统计 SO2监测浓度(μg/m³) 的取值情况:

存在16个数据取值为负数,由于浓度大于等于0,所以对取值为负数的异常值进行处理。

未处理前的数据情况:

返回文章目录

删除异常值

由于 SO2监测浓度(μg/m³) 取值为负数的数据个数并不多,所以将 SO2监测浓度(μg/m³) 取值为负数的行直接删除。

# 包的引入
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 读取数据
data = pd.read_excel('../22/监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_数据填补.xlsx')
# 删除 SO2监测浓度(μg/m³) 取值为负数的行
# 即取出 SO2监测浓度(μg/m³) 取值大于等于0的行
re = data[data['SO2监测浓度(μg/m³)']>=0]
re.count()

返回文章目录

异常值置为空值

未处理前的数据情况:

# 包的引入
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 读取数据
data = pd.read_excel('../22/监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_数据填补.xlsx')
# 深复制一份数据
data1 = data.copy() 
# 将 SO2监测浓度(μg/m³) 列中取值为负数的数据置为空值
data1['SO2监测浓度(μg/m³)'][data1['SO2监测浓度(μg/m³)']<0] = pd.NA
data1.count()

返回文章目录

2.2.2 基于 3σ 准则(拉依达准则)的异常值处理

这里只进行异常值的筛选,不进行处理,若要处理可以采用与 2.2.1 中类似的方法进行处理,删除异常值或者置为空值后填补异常值。

# 包的引入
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 提高 matplotlib 在 jupyter 中作图的分辨率
%config InlineBackend.figure_format = 'retina'
# 处理中文与负号的显示问题
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
data = pd.read_excel('../22/监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_数据填补.xlsx')
# 获取 SO2监测浓度(μg/m³) 列
so2 = data['SO2监测浓度(μg/m³)']
# 计算均值与标准差
mean_so2 = so2.mean()
std_so2 = so2.std()
print(mean_so2, std_so2)
# 计算 μ-3σ μ+3σ
left = mean_so2 - 3*std_so2
right = mean_so2 + 3*std_so2
# 绘制数据分布图
# ax 接收返回的坐标轴对象
ax = sns.distplot(
  # 绘制图形的数据
  data['SO2监测浓度(μg/m³)'],
  # 显示变量的分布情况
  rug=True,
  # 设置x轴的标签
  axlabel= r'$SO_{2}$'
)
# 绘制 μ-3σ μ+3σ
plt.axvline(left, linestyle='--', color='orange')
plt.axvline(right, linestyle='--', color='orange')
# 显示图例
plt.legend()
plt.show()
# 复制数据集
data1 = data.copy()
# 筛选出 SO2监测浓度(μg/m³) 列取值不在 (μ-3σ, μ+3σ) 内的行
data1 = data1[np.abs(data1['SO2监测浓度(μg/m³)']-mean_so2) > 3*std_so2]
data1

均值与标准差

基于 3σ 准则(拉依达准则) 筛选出的 SO2监测浓度(μg/m³) 取值异常的行:

返回文章目录

2.2.3 基于箱线图检测的异常值处理

这里只进行异常值的筛选,不进行处理,若要处理可以采用与 2.2.1 中类似的方法进行处理,删除异常值或者置为空值后填补异常值。

# 包的引入
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 提高 matplotlib 在 jupyter 中作图的分辨率
%config InlineBackend.figure_format = 'retina'
# 处理中文与负号的显示问题
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 读取数据
data = pd.read_excel('../22/监测点A逐小时污染物浓度与气象实测数据_去除整行缺失_数据填补.xlsx')
# 获取 SO2监测浓度(μg/m³) 列
so2 = data['SO2监测浓度(μg/m³)']
# 绘制箱线图
plt.boxplot(
  # 绘图数据
  so2,
  # 填充箱体颜色
  patch_artist=True,
  # 显示平均值,默认使用点显示
  showmeans=True,
  # 设置箱子的宽度
  widths=0.1,
  # 设置箱子的样式,需要 patch_artist=True
  boxprops={
    # 箱子的边框为黑色
    'color': 'k',
    # 箱子的填充色为橙色
    'facecolor': 'orange',
  },
  # 设置异常值点的样式
  flierprops={
    # 设置点的形状
    'marker': '.',
    # 设置点的填充色
    'markerfacecolor': 'blue',
    # 设置点的边框色
    'markeredgecolor': 'blue',
    # 设置点的大小
    'markersize': '2'
  },
  # 添加箱线图在x轴对应位置的名字
  # x轴坐标点名
  labels=['SO2监测浓度'],
)
plt.grid(linestyle=':')
# 显示图例
plt.legend()
plt.show()
# 获取 SO2监测浓度(μg/m³) 的上下四分位数
bottom, top = so2.quantile([.25, .75])
print('下四分位数: ', bottom, '上四分位数', top)
# 计算 IQR
IQR = top - bottom
print('IQR: ', IQR)
# 计算异常值截断点
top_error = top + 1.5*IQR
bottom_error = bottom - 1.5*IQR
print('异常值截断点', bottom_error, top_error)
# 复制数据集
data1 = data.copy()
data1 = data1[(so2>top_error) | (so2<bottom_error)]
data1

基于箱线图检测筛选出的 SO2监测浓度(μg/m³) 取值异常的行:

返回文章目录

3. 重复值处理

  • 数据集中出现重复值有以下几种情况:
  • 1.不同行之间在各列上的取值均相同,即不同行的数据取值完全一致。
  • 2.不同行之间存在在某些列上的取值相同

对于重复值可以根据需要,选择对全部列进行去重,也可以选择对某些列进行去重。

可以使用 DataFrame.drop_duplicates() 方法来处理重复值。

  • DataFrame.drop_duplicates()
  • 参数:
  • subset:接收 string 或 序列 为参数,表示要进行去重的列,默认为None,表示全部的列(只有当一行中所有的列一样,才会对该行进行去重)
  • keep:接收 string 为参数,表示重复时保留第几个数据。first:保留第一个。last:保留最后一个。false:只要有重复都不保留。默认为first。
  • inplace:表示是否在原表上进行修改。默认为False。

默认情况下,对所有的列进行去重,不在原表上进行修改,有重复值时默认保留重复值的第一个。

代码示例:

l = [
  np.array([1,2,3]),
  np.array([1,1,2]),
  np.array([1,1,2]),
  np.array([1,1,1])
]
df = pd.DataFrame(l)
print(df)
print()
print(df.drop_duplicates())
print()
print(df)

l = [
  np.array([1,2,3]),
  np.array([1,1,2]),
  np.array([1,1,2]),
  np.array([1,1,1])
]
df = pd.DataFrame(l)
print(df)
print()
# 在原表上进行修改,无返回值
# 不在原表上进行修改,会返回修改后的新表
# 对第一第二列的数据进行去重,保留重复值的最后一个
print(df.drop_duplicates(subset=[0,1], inplace=True, keep='last'))
print()
print(df)



相关文章
|
5天前
|
人工智能 Shell 开发工具
[oeasy]python065python报错怎么办_try_试着来_except_发现异常
本文介绍了Python中处理异常的基本方法,重点讲解了`try`和`except`的用法。通过一个计算苹果重量的小程序示例,展示了如何捕获用户输入错误并进行处理。主要内容包括: 1. **回顾上次内容**:简要回顾了Shell环境、Python3游乐场和Vim编辑器的使用。 2. **编写程序**:编写了一个简单的程序来计算苹果的总重量,但发现由于输入类型问题导致结果错误。 3. **调试与修正**:通过调试发现输入函数返回的是字符串类型,需要将其转换为整数类型才能正确计算。
48 32
|
3天前
|
数据库 Python
[oeasy]python066_如何捕获多个异常_try_否则_else_exception
本文介绍了Python中`try...except...else`结构的使用方法。主要内容包括: 1. **回顾上次内容**:简要复习了`try`和`except`的基本用法,强调了异常处理的重要性。 2. **详细解释**: - `try`块用于尝试执行代码,一旦发现错误会立即终止并跳转到`except`块。 - `except`块用于捕获特定类型的异常,并进行相应的处理。 - `else`块在没有异常时执行,是可选的。 3. **示例代码**:通过具体例子展示了如何捕获不同类型的异常(如`ValueError`和`ZeroDivisionError`),并解释了异常处理
33 24
|
22天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
Python
课程设计项目之基于Python实现围棋游戏代码
游戏进去默认为九路玩法,当然也可以选择十三路或是十九路玩法 使用pycharam打开项目,pip安装模块并引用,然后运行即可, 代码每行都有详细的注释,可以做课程设计或者毕业设计项目参考
78 33
|
2月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
51 10
|
2月前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
103 8
|
9月前
|
算法 编译器 开发者
如何提高Python代码的性能:优化技巧与实践
本文探讨了如何提高Python代码的性能,重点介绍了一些优化技巧与实践方法。通过使用适当的数据结构、算法和编程范式,以及利用Python内置的性能优化工具,可以有效地提升Python程序的执行效率,从而提升整体应用性能。本文将针对不同场景和需求,分享一些实用的优化技巧,并通过示例代码和性能测试结果加以说明。
|
5月前
|
人工智能 数据挖掘 数据处理
揭秘Python编程之美:从基础到进阶的代码实践之旅
【9月更文挑战第14天】本文将带领读者深入探索Python编程语言的魅力所在。通过简明扼要的示例,我们将揭示Python如何简化复杂问题,提升编程效率。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编码世界的大门。让我们开始这段充满智慧和乐趣的Python编程之旅吧!
|
3月前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习:从理论到Python代码实践
【10月更文挑战第36天】本文将深入浅出地介绍机器学习的基本概念、主要算法及其在Python中的实现。我们将通过实际案例,展示如何使用scikit-learn库进行数据预处理、模型选择和参数调优。无论你是初学者还是有一定基础的开发者,都能从中获得启发和实践指导。
87 2
|
4月前
|
大数据 Python
Python 高级编程:深入探索高级代码实践
本文深入探讨了Python的四大高级特性:装饰器、生成器、上下文管理器及并发与并行编程。通过装饰器,我们能够在不改动原函数的基础上增添功能;生成器允许按需生成值,优化处理大数据;上下文管理器确保资源被妥善管理和释放;多线程等技术则助力高效完成并发任务。本文通过具体代码实例详细解析这些特性的应用方法,帮助读者提升Python编程水平。
205 5

热门文章

最新文章