第二章 数据处理

一、缺失值处理
数据缺失主要包括记录缺失和字段信息缺失等情况,其对数据分析会有较大影响,导致结果不确定性更加显著
1.判断是否有缺失值数据 - isnull,notnull

print(s.isnull())  # Series直接判断是否是缺失值,返回一个Series
print(df.notnull())  # Dataframe直接判断是否是缺失值,返回一个Series
print(df['value1'].notnull())  # 通过索引判断

2.删除缺失值 - dropna

s.dropna(inplace = True)   # 注意inplace参数,默认False → 生成新的值
df2 = df['value1'].dropna()   # drop方法:可直接用于Series,Dataframe

3.填充/替换缺失数据 - fillna、replace

s.fillna(0,inplace = True)   # s.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)# value:填充值
df['value1'].fillna(method = 'pad',inplace = True)   # method参数:# pad / ffill → 用之前的数据填充    # backfill / bfill → 用之后的数据填充   
s.replace(np.nan,'缺失数据',inplace = True)   # df.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad', axis=None)# to_replace → 被替换的值   # value → 替换值
s.replace([1,2,3],np.nan,inplace = True)  # 多值用np.nan代替

4.缺失值插补
① 均值/中位数/众数插补

u = s.mean()     # 均值
me = s.median()  # 中位数
mod = s.mode()   # 众数
s.fillna(u,inplace = True)

② 临近值插补

s.fillna(method = 'ffill',inplace = True)   # 用前值插补

③ 插值法 —— 拉格朗日插值法

from scipy.interpolate import lagrange
x = [3, 6, 9]
y = [10, 8, 4]
print(lagrange(x,y))   # 输出值为n个系数的多项式,这里输出3个值,分别为a0,a1,a2
print(type(lagrange(x,y)))   # y = a0 * x**2 + a1 * x + a2 → y = -0.11111111 * x**2 + 0.33333333 * x + 10
print('插值10为:%.2f' % lagrange(x,y)(10))   # -0.11111111*100 + 0.33333333*10 + 10 = -11.11111111 + 3.33333333 +10 = 2.22222222
插值法 —— 拉格朗日插值法,实际运用
data = pd.Series(np.random.rand(100)*100)
data[3,6,33,56,45,66,67,80,90] = np.nan
# 创建数据
data_na = data[data.isnull()]
print('缺失值数据量:%i' % len(data_na))
print('缺失数据占比:%.2f%%' % (len(data_na) / len(data) * 100))
# 缺失值的数量
data_c = data.fillna(data.median())  #  中位数填充缺失值
fig,axes = plt.subplots(1,4,figsize = (20,5))
data.plot.box(ax = axes[0],grid = True,title = '数据分布')
data.plot(kind = 'kde',style = '--r',ax = axes[1],grid = True,title = '删除缺失值',xlim = [-50,150])
data_c.plot(kind = 'kde',style = '--b',ax = axes[2],grid = True,title = '缺失值填充中位数',xlim = [-50,150])
# 密度图查看缺失值情况
def na_c(s,n,k=5):
    y = s[list(range(n-k,n+1+k))] # 取数
    y = y[y.notnull()]  # 剔除空值
    return(lagrange(y.index,list(y))(n))
# 创建函数,做插值,由于数据量原因,以空值前后5个数据(共10个数据)为例做插值
na_re = []
for i in range(len(data)):
    if data.isnull()[i]:
        data[i] = na_c(data,i)
        print(na_c(data,i))
        na_re.append(data[i])
data.dropna(inplace=True)  # 清除插值后仍存在的缺失值
data.plot(kind = 'kde',style = '--k',ax = axes[3],grid = True,title = '拉格朗日插值后',xlim = [-50,150])
print('finished!')
# 缺失值插值

二、异常值处理
1.3σ原则
如果数据服从正态分布,异常值被定义为一组测定值中与平均值的偏差超过3倍的值 → p(|x - μ| > 3σ) ≤ 0.003

error = data[np.abs(data - u) > 3*std]
data_c = data[np.abs(data - u) <= 3*std]
# 筛选出异常值error、剔除异常值之后的数据data_c
plt.scatter(data_c.index,data_c,color = 'k',marker='.',alpha = 0.3)
plt.scatter(error.index,error,color = 'r',marker='.',alpha = 0.5)

这里写图片描述
2.箱型图分析
箱型图看数据分布情况,以内限为界
这里写图片描述
三、数据归一化/标准化
数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。
在某些比较和评价的指标处理中经常会用到,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权
最典型的就是数据的归一化处理,即将数据统一映射到[0,1]区间上
1.0-1标准化
将数据的最大最小值记录下来,并通过Max-Min作为基数(即Min=0,Max=1)进行数据的归一化处理
x = (x - Min) / (Max - Min)

def data_norm(df,*cols):
    df_n = df.copy()
    for col in cols:
        ma = df_n[col].max()
        mi = df_n[col].min()
        df_n[col + '_n'] = (df_n[col] - mi) / (ma - mi)
    return(df_n)   # 创建函数,标准化数据
df_n = data_norm(df,'value1','value2')   # 标准化数据

2.Z-score标准化
Z分数(z-score),是一个分数与平均数的差再除以标准差的过程 → z=(x-μ)/σ,其中x为某一具体分数,μ为平均数,σ为标准差
Z值的量代表着原始分数和母体平均值之间的距离,是以标准差为单位计算。在原始分数低于平均值时Z则为负数,反之则为正数

def data_Znorm(df, *cols):
    df_n = df.copy()
    for col in cols:
        u = df_n[col].mean()
        std = df_n[col].std()
        df_n[col + '_Zn'] = (df_n[col] - u) / std
    return(df_n)   # 创建函数,标准化数据
df_z = data_Znorm(df,'value1','value2')   # 标准化数据
# 经过处理的数据符合标准正态分布,即均值为0,标准差为1
# 在分类、聚类算法中,需要使用距离来度量相似性的时候,Z-score表现更好

四、数据连续属性离散化
连续属性变换成分类属性,即连续属性离散化
在数值的取值范围内设定若干个离散划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表每个子区间中的数据值
1.等宽法(cut方法) → 将数据均匀划分成n等份,每份的间距相等

bins = [18,25,35,60,100]
cats = pd.cut(ages,bins)

2.等频法(qcut方法) → 以相同数量的记录放进每个区间

s = pd.Series(data)
cats = pd.qcut(s,4)  # 按四分位数进行切割,可以试试 pd.qcut(data,10)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值