数据预处理_缺失值

缺失值处理

  • 数据缺失主要包括记录缺失和字段信息缺失等情况,其对数据分析会有较大影响,导致结果不确定性更加显著
  • 缺失值处理
    • 丢弃 → 删除
    • 插补 → 均值、中位数、众数插补 / 临近值插补 / 插值法
    • 不处理
# 设置cell多行输出

from IPython.core.interactiveshell import InteractiveShell 
InteractiveShell.ast_node_interactivity = 'all' #默认为'last'

# 导入相关库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings

warnings.filterwarnings('ignore')
os.chdir(r'E:\python_learn\data')
file_name = 'iris-data.csv'
iris_data = pd.read_csv(file_name,engine='python')
iris_data.head()
sepal_length_cm sepal_width_cm petal_length_cm petal_width_cm class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 NaN Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa

本次缺失值处理使用的数据集为修改过的鸢尾花卉数据,将对该数据集进行缺失值处理和异常值处理等操作。

其中,sepal_length_cm为花萼长度,sepal_width_com为花萼宽度

petal_length_cm为花瓣长度,petal_length_cm为花瓣宽度

通过这4个数据,能判断并分类出3种鸢尾花的类别,class为鸢尾花类别

# 查看数基本结构
iris_data.info()

# 一共150条数据,5个字段
# 从返回基本结构可以看到除了class字段,其他字段都含有缺失值
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
sepal_length_cm    147 non-null float64
sepal_width_cm     148 non-null float64
petal_length_cm    144 non-null float64
petal_width_cm     144 non-null float64
class              150 non-null object
dtypes: float64(4), object(1)
memory usage: 5.9+ KB
# 缺失值判断
iris_data.isna().sum()
sepal_length_cm    3
sepal_width_cm     2
petal_length_cm    6
petal_width_cm     6
class              0
dtype: int64

丢弃处理

  • 删除带缺失值记录或列字段,虽减少缺失值对样本的影响,但也意味着减少数据特征。
  • 以下2种情况不宜丢弃处理缺失值:
    • 缺失值超过比例较大,超过10%
    • 带缺失值的label标签主要集中于某一类或几类,删除会使样本丢失大量特征信息
  • 丢弃处理 → 用pandas的dropna()方法,删除含NaN的行或列
iris_dropna_1 = iris_data.dropna()    # 缺失值删除处理
# 默认how=any,axis=0,行记录任意出现NaN就删除行记录

iris_dropna_1.isna().sum()  
iris_dropna_1.isna().sum().sum()  # 缺失值检查
sepal_length_cm    0
sepal_width_cm     0
petal_length_cm    0
petal_width_cm     0
class              0
dtype: int64

0
iris_dropna_2 = iris_data.dropna(how='all')  # 缺失值删除处理
# how=all,当整行记录都为NaN才删除记录

iris_dropna_2.isna().sum()  
iris_dropna_2.isna().sum().sum()  # 缺失值检查,发现并没有删除,表示不存在整行都为NaN的情况
sepal_length_cm    3
sepal_width_cm     2
petal_length_cm    6
petal_width_cm     6
class              0
dtype: int64

17

因本次演练数据集样本量较少,不选择删除缺失值的处理方法

插补处理

均值/中位数/众数插补
→ pandas的fillna()方法

iris_fillna_1 = iris_data.fillna(iris_data.median())  # 在不确定是否存在异常值时,此处选择时候中位数填补
iris_fillna_1.isna().sum()
sepal_length_cm    0
sepal_width_cm     0
petal_length_cm    0
petal_width_cm     0
class              0
dtype: int64

均值/中位数/众数插补
→ sklearn的数据预处理方法

from sklearn.impute import SimpleImputer
iris_nan_model = SimpleImputer(missing_values=np.nan,strategy='median')   # 用中位数替换NaN
iris_nan_result = iris_nan_model.fit_transform(np.array(iris_data)[:,:4]) # 应用模型,数据以数组形式传入
iris_result = pd.DataFrame(iris_nan_result,columns=['sepal_length_cm','sepal_width_cm','petal_length_cm','petal_width_cm'])

iris_result.isna().sum()
iris_result.isna().sum().sum()
sepal_length_cm    0
sepal_width_cm     0
petal_length_cm    0
petal_width_cm     0
dtype: int64

0

临近值插补
→ pandas的fillna()方法,设置method参数;method=ffill,用前面值替换NaN;method=bfill,用后面值替换NaN

iris_data.head()
iris_fillna_2 = iris_data.fillna(method='ffill')
iris_fillna_2.head()

iris_result.isna().sum()
iris_result.isna().sum().sum()
sepal_length_cm sepal_width_cm petal_length_cm petal_width_cm class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 NaN Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
sepal_length_cm sepal_width_cm petal_length_cm petal_width_cm class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
sepal_length_cm    0
sepal_width_cm     0
petal_length_cm    0
petal_width_cm     0
dtype: int64






0

插值法
→ 拉格朗日插值法

拉格朗日插值法:将缺失函数值对应的点x代入插值多项式得到缺失值的近似值L(x)

from scipy.interpolate import lagrange   # 导入拉格朗日插值函数

iris_lagrange = iris_data.copy()  # 复制一份原数据,用于操作
print(iris_lagrange.head())

# 自定义列向量插值函数
# s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_columnn(s,n,k=5):
    y = s[list(range(n-k,n))+list(range(n+1,n+1+k))]   # 取数
    y = y[y.notna()]                                    # 剔除空值
    return lagrange(y.index,list(y))(n)                 # 插值并返回插值结果

# 逐个元素判断是否需要插值
for i in iris_lagrange.columns:
    for j in range(len(iris_lagrange)):
        if (iris_lagrange[i].isna())[j]:
            iris_lagrange[i][j] = ployinterp_columnn(iris_lagrange[i],j)

iris_lagrange.isna().sum()
iris_lagrange.isna().sum().sum()  # 缺失值检查
print(iris_lagrange.head())
   sepal_length_cm  sepal_width_cm  petal_length_cm  petal_width_cm  \
0              5.1             3.5              1.4             0.2   
1              4.9             3.0              1.4             0.2   
2              4.7             3.2              1.3             NaN   
3              4.6             3.1              1.5             0.2   
4              5.0             3.6              1.4             0.2   

         class  
0  Iris-setosa  
1  Iris-setosa  
2  Iris-setosa  
3  Iris-setosa  
4  Iris-setosa  





sepal_length_cm    0
sepal_width_cm     0
petal_length_cm    0
petal_width_cm     0
class              0
dtype: int64






0



   sepal_length_cm  sepal_width_cm  petal_length_cm  petal_width_cm  \
0              5.1             3.5              1.4        0.200000   
1              4.9             3.0              1.4        0.200000   
2              4.7             3.2              1.3        0.273333   
3              4.6             3.1              1.5        0.200000   
4              5.0             3.6              1.4        0.200000   

         class  
0  Iris-setosa  
1  Iris-setosa  
2  Iris-setosa  
3  Iris-setosa  
4  Iris-setosa  
发布了10 篇原创文章 · 获赞 0 · 访问量 18

猜你喜欢

转载自blog.csdn.net/weixin_45556639/article/details/105473803