营销型网站建设主要教学内容,青浦网站设计制作,网站建设推广优化,网站开发品牌删除空行
#del all None value
data_all.dropna(axis1, howall, inplaceTrue)
删除空列
#del all None value
data_all.dropna(axis0, howall, inplaceTrue)
缺失值处理
观测缺失值 观测数据缺失值有一个比较好用的工具包——missingno#xff0c;直接传入DataFrame…删除空行
#del all None value
data_all.dropna(axis1, howall, inplaceTrue)
删除空列
#del all None value
data_all.dropna(axis0, howall, inplaceTrue)
缺失值处理
观测缺失值 观测数据缺失值有一个比较好用的工具包——missingno直接传入DataFrame会将所有的列缺失比例可视化是一个比较方便的工具。 将观测的缺失值数据统计成为一个数据表并将数据表可视化
# 统计缺失值数量
missingdata_all.isnull().sum().reset_index().rename(columns{0:missNum})
# 计算缺失比例
missing[missRate]missing[missNum]/data_all.shape[0]
# 按照缺失率排序显示
miss_analymissing[missing.missRate0].sort_values(bymissRate,ascendingFalse)
# miss_analy 存储的是每个变量缺失情况的数据框 然后将缺失值数据miss_analy可视化
import matplotlib.pyplot as plt
import pylab as pl
fig plt.figure(figsize(18,6))
plt.bar(np.arange(miss_analy.shape[0]), list(miss_analy.missRate.values), align center,color[red,green,yellow,steelblue])
plt.title(Histogram of missing value of variables)
plt.xlabel(variables names)
plt.ylabel(missing rate)# 添加x轴标签并旋转90度
plt.xticks(np.arange(miss_analy.shape[0]),list(miss_analy[index]))
plt.xticks(rotation90)
# 添加数值显示
for x,y in enumerate(list(miss_analy.missRate.values)): plt.text(x,y0.12,{:.2%}.format(y),hacenter,rotation90) plt.ylim([0,1.2])
plt.show() 当然有些画图的技巧需要每个人根据各自的需求去探索笔者画图功底也比较差可以参考Sklearn里面的sample也可以查阅Seaborn中的技术文档。以上数据可视化后可以看到每一列的缺失值比例然后可以自己设定缺失值阈值α如果缺失值比例大于α则删除该列或者其他却缺失值处理策略。当然笔者任务是建立高精度的预测模型而且数据量还可以。所以就没有用填充策略。
删除缺失严重特征
alpha 0.2
need_delete_cols []
for index,row in miss_analy.iterrows():if row[missRate] alpha:need_delete_cols.append(row[index])#delete most empty col
data_all data_all.drop(columnsneed_delete_cols, axis0, inplaceTrue) 有的人可能觉得这种方法比较麻烦又要可视化又要单独删除如果不需要可视化或者探索缺失值的具体情况我这里也提供一个非常简单粗暴的缺失值删除办法
data_alldata_all.dropna(threshlen(data_all)*alpha, axis1) 以上一行代码完成了前述的所有删除工作。
删除单值特征 单值特征是指某一列只有一个值不存在变化的情况这种特征是没有任何意义的需要直接删除
desc data_all.astype(str).describe()
mask desc.loc[unique,:] 1
data_all.drop(labelsdesc.columns[mask],axis1,inplaceTrue)
异常数据处理 这里我说的异常数据一般是指每个特征中的离群数据因为我的任务是建立一个通用的泛化能力较强的模型所以这里对每个特征的离群数据进行删除操作避免后续模型为了拟合离群点导致过拟合的现象。那如何判断某个数据点是否离群或者异常呢这里提供两种方法每个方法都有优劣势后续我再细说。
3σ方式 用传统意义上的统计方法实现3σ我就不细说了正态分布3σ之外的数据为异常
def del_outlier(dataset):temp dataset.copy()for each in temp.columns:std np.std(temp[each])mean np.mean(temp[each])sigma 4 * stdlimit_up mean sigma limit_bottom mean - sigma temp temp.query(({} {}) and ({} {}).format(each,limit_bottom,each,limit_up))print(limit_up,limit_bottom)print(each,temp.shape)return temp 这个方式比较通用最适合看起来服从正太分布的特征。
分位数方式 首先我放个连接(https://www.itl.nist.gov/div898/handbook/prc/section1/prc16.htm)里面描述了什么是离群点。
def del_outlier(dataset):temp dataset.copy()for each in temp.columns: first_quartile temp[each].describe()[25%]third_quartile temp[each].describe()[75%]iqr third_quartile - first_quartilelimit_up third_quartile 3 * iqrlimit_bottom first_quartile - 3 * iqr temp temp.query(({} {}) and ({}{}).format(each,limit_bottom,each,limit_up))print(limit_up,limit_bottom)print(each,temp.shape)return temp 分位数方式存在一个问题如果离群点非常少导致3/4和1/4分位数相等就无法执行下去。
个人还是比较推荐σ的方法。
特征信息量 特诊信息量是描述的某一特征的数据是否有足够的信息熵去辅助建模如果一个特诊的信息熵很低那说明该特诊基本上不存在什么波动蕴含的信息量极少(当然可能要做完归一化后观测起来会比较明显)那该特诊就可以直接删除。 以下为计算信息熵的Python代码
from scipy.stats import entropy
from math import log, e
import pandas as pd ## Usage: pandas_entropy(df[column1]) def pandas_entropy(column, baseNone):vc pd.Series(column).value_counts(normalizeTrue, sortFalse)base e if base is None else basereturn -(vc * np.log(vc)/np.log(base)).sum()
执行删除信息熵小的特诊
for each in feature_list:
# print(each,pandas_entropy(data_all[each]))if pandas_entropy(data_all[each]) 1:print(each,pandas_entropy(data_all[each]))data_all.drop(columns[each],axis1,inplaceTrue)
处理不同数据类型特诊(时间特征为例) DataFrame数据类型通常包含Objectint64float64,对于后两者我们没必要可以去改变但是对于Object类型的数据不同含义的Object数据做不同处理。笔者这里举例时间格式的Object数据处理。 数据类型查看与统计
data_all.dtypes.values_counts() 将时间的Object数据进行转换。
data_all[key] pd.to_datetime(data_all[key])如果存在类似开始时间-结束时间的时间对数据可以将两者相减得到时间片段数据例如
data_all[time_gap] pd.to_datetime(data_all[end]) - pd.to_datetime(data_all[start]) 然后将时间段数据转为小时或者分钟或者秒
data_all[key] data_all[key].apply(lambda x: x.total_seconds() / 60 / 60)
以上为个人通常来讲的数据预处理过程建议在每执行一步后数据重新命名并保存一份备份。
以上。 如有什么建议或者错误大家随时拍砖。