data1=data.dropna()#丢弃缺失值
#dropna()删除缺失值所在行(axis=0)或列(axis=1),默认为 axis=0
import pandas as pd
import numpy as np
data = pd.DataFrame({
'name': ['Bob', 'Mary', 'Peter', np.nan, 'Lucy'],
'score': [99, 100, np.nan, 91, 95],
'class': ['class1', 'class2', 'class1', 'class2', np.nan],
'sex': ['male', 'fmale', 'male', 'male', 'fmale'],
'age': [23, 25, 20, 19, 24]
})
(1)均值填充
#对data数据中的score进行均值填充
data['score'].fillna(data['score'].mean())
# 结果如下
0 99.00
1 100.00
2 96.25
3 91.00
4 95.00
(2)中位数填充
#对data数据中的score进行中位数填充
data['score'].fillna(data['score'].median())
# 结果如下
0 99.0
1 100.0
2 97.0
3 91.0
4 95.0
data
数据中的class
进行众数填充(注意:众数填充时要通过索引0进行取值,一组数据的众数可能有多个,索引为0的数据一定会存在) data['class'].fillna(data['class'].mode()[0])
# 结果如下
0 class1
1 class2
2 class1
3 class2
4 class1
#代码示例:对data数据中的score进行前后数据填充
# 前文填充
data['score'].fillna(method='pad')
# 后文填充
data['score'].fillna(method='bfill')
# 前文填充结果
0 99.0
1 100.0
2 100.0
3 91.0
4 95.0
# 后文填充结果
0 99.0
1 100.0
2 91.0
3 91.0
4 95.0
(5)自定义数据填充
#代码示例:对data数据中的name进行自定义数据填充
data['name'].fillna('no_name')
# 结果如下
0 Bob
1 Mary
2 Peter
3 no_name
4 Lucy
(6)Pandas插值填充
适用场景:数据列的含义较为复杂,需要更精确的填充方法时
举例:对所有带有nan的数值列dataframe进行填充
说明:pandas中进行空值填充的方法为interpolate(),该方法的本质是使用各种数学(统计学)中的插值方法进行填充,其中包含最近邻插值法、阶梯插值、线性插值、B样条曲线插值等多种方法。
data['score'].interpolate()
# 结果如下
0 99.0
1 100.0
2 95.5
3 91.0
4 95.0
(7)建模填充
from sklearn.linear_model import LinearRegression
# 获取数据
data_train = data.iloc[[0, 1, 3]]
data_train_x = data_train[['age']]
data_train_y = data_train['score']
# 使用线性回归进行拟合
clf = LinearRegression()
clf.fit(data_train_x, data_train_y)
# 使用预测结果进行填充
data['score'].iloc[2] = clf.predict(pd.DataFrame(data[['age']].iloc[2]))
from sklearn.tree import DecisionTreeClassifier
# 获取数据
data_train = data.iloc[[0, 1, 3]]
data_train_x = data_train[['age']]
data_train_y = data_train['class']
# 使用决策树进行拟合
clf = DecisionTreeClassifier()
clf.fit(data_train_x, data_train_y)
# 使用分类结果进行填充
data['class'].iloc[4] = clf.predict(pd.DataFrame(data[['age']].iloc[4]))[0]
异常值检测
1、3∂原则
要求:数据服从或近似服从正态分布
在3∂原则下,异常值如超过3倍标准差,那么可以将其视为异常值。正负3∂的概率是99.7%,那么距离平均值3∂之外的值出现的概率为P(|x-u| > 3∂) <= 0.003,属于极个别的小概率事件。如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。
需要注意的是,3σ方法假设数据服从正态分布,因此在应用时要确保数据的分布近似于正态分布。如果数据不满足这个假设,其他异常值检测方法可能更合适。此外,3σ方法可能对极端值(outliers)不够敏感,因此在某些情况下可能会漏检一些异常值。因此,在实际应用中,通常需要结合其他方法进行异常值检测,以提高检测的准确性。
首先检验数据是否正态分布
# pvalue大于0.05则认为数据呈正态分布
from scipy import stats
mean = df['age'].mean()
std = df['age'].std()
print(stats.kstest(df['age'],'norm',(mean,std)))
异常值处理
# 选取小于3个标准差的数据
data = data[np.abs(df['age']- mean) <= 3*std]
如果数据不符合正态分布,也可以用远离平均值的多少倍标准差来筛选异常值。具体倍数看数据情况和业务需求
# 定义远离平均值4倍标准差为异常值
a = mean + std*4
b = mean - std*4
data = data[(data['Age'] <= a) & (data['Age'] >= b)]
或者定义为函数:
def three_sigma(s):
mu, std = np.mean(s), np.std(s)
lower, upper = mu-3*std, mu+3*std
return lower, upper
2、箱型图
利用箱型图的四分位距(IQR)对异常值进行检测,四分位距(IQR)就是上四分位与下四分位的差值。而我们通过IQR的1.5倍为标准,规定:超过上四分位+1.5倍IQR距离,或者下四分位-1.5倍IQR距离的点为异常值。
numpy
的percentile
方法。
data = np.array([2, 2, 3, 4, 5, 6, 7, 8, 1000])
Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = np.where((data < lower_bound) | (data > upper_bound))
print("异常值的索引:", outliers)
boxplot
来实现:
f,ax=plt.subplots(figsize=(10,8))
sns.boxplot(y='length',data=df,ax=ax)
plt.show()
#或者用pandas自身的plot方法
data['Age'].plot(kind = 'box')
3、标准差的方法(Z-Score)
import numpy as np
from scipy import stats
data = np.array([2, 2, 3, 4, 5, 6, 7, 8, 1000])
z_scores = np.abs(stats.zscore(data))
threshold = 3
outliers = np.where(z_scores > threshold)
print("异常值的索引:", outliers)
Smoothed Z-Score
通过计算数据点与其周围数据点的标准差来识别异常值,从而将数据平滑化。计算过程如下:
计算滑动窗口内的均值和标准差: 首先,你需要选择一个滑动窗口大小,通常是一个时间窗口(例如,10天)。然后,对于每个数据点,计算在该滑动窗口内的均值(mean)和标准差(standard deviation)。
计算 Z-Score: 对于每个数据点,计算其与滑动窗口内均值的差值,然后除以滑动窗口内的标准差,得到 Z-Score。
平滑 Z-Score: 对计算得到的 Z-Score 序列应用一种平滑技术,例如指数移动平均(Exponential Moving Average,EMA)或简单移动平均(Simple Moving Average,SMA),以减少噪音和平滑数据。
设定阈值: 最后,根据平滑后的 Z-Score,你可以设定一个阈值来识别异常值。如果平滑后的 Z-Score 超过或低于阈值,那么该数据点就被认为是异常值。
对于时间序列数据和需要考虑噪音的情况,Smoothed Z-Score 可能更适合,而对于符合正态分布假设的数据集,Z-Score 通常足够用来检测异常值。
4、基于密度的方法(DBSCAN)
from sklearn.cluster import DBSCAN
import numpy as np
data = np.array([[2], [2], [3], [4], [5], [6], [7], [8], [1000]])
dbscan = DBSCAN(eps=0.5, min_samples=2)
labels = dbscan.fit_predict(data)
outliers = np.where(labels == -1)
print("离群值的索引:", outliers)
5、Isolation Forest(孤立森林):
from sklearn.ensemble import IsolationForest
import numpy as np
data = np.array([[2], [2], [3], [4], [5], [6], [7], [8], [1000]])
isolation_forest = IsolationForest(contamination=0.05)
labels = isolation_forest.fit_predict(data)
outliers = np.where(labels == -1)
print("离群值的索引:", outliers)
常值处理方法
标准化