一、缺失值
1.空值判斷
isnull()空值為True,非空值為False
notnull() 空值為False,非空值為True
s = pd.Series([1,2,'3',np.nan,'hello',np.nan]) df = pd.DataFrame({'a':[1,2,np.nan,'3'],'b':[2,np.nan,'3','hello']}) print(s.isnull()) print(s[s.isnull() == False]) #求s中的非空值,或者直接s[s.notnull()]print(df.notnull()) print(df[df['b'].notnull()]) #求s中的非空值,或者df[df.isnull() == False]


0 False 1 False 2 False 3 True 4 False 5 True dtype: bool 0 1 1 2 2 3 4 hello dtype: objecta b 0 True True 1 True False 2 False True 3 True Truea b 0 1 2 2 NaN 3 3 3 hello
?
2.空值刪除
dropna()刪除所有出現空值的行,即任何一個字段出現空值該行都會被刪除。
dropna()默認返回刪除空值后的數據且不修改原數據,加參數inplace=True直接修改原數據
s = pd.Series([1,2,'3',np.nan,'hello',np.nan]) df = pd.DataFrame({'a':[1,2,np.nan,'3'],'b':[2,np.nan,'3','hello']}) print(s.dropna()) df.dropna(inplace = True) print(df)


0 1
1 2
2 3
4 hello
dtype: objecta b
0 1 2
3 3 hello
?
3.空值填充
fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
value 指定value填充空值,默認為None
method 填充方法,backfill/bfill使用后面的值填充,pad/ffill使用前面的值填充,默認為None
inplace 默認為False不修改原數據
limit 如果有多個空值,最多修改多少個
s = pd.Series([1,2,'3',np.nan,'hello',np.nan]) df = pd.DataFrame({'a':[1,2,np.nan,'3'],'b':[2,np.nan,'3','hello']}) print(s.fillna(0)) print(s.fillna(0,limit = 1)) print(df.fillna(method = 'bfill'))


0 1 1 2 2 3 3 0 4 hello 5 0 dtype: object 0 1 1 2 2 3 3 0 4 hello 5 NaN dtype: objecta b 0 1 2 1 2 3 2 3 3 3 3 hello In [41]:
?
4.空值替換
replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')
to_replace 被替換值
value 替換值
method 如果不指定value,使用method指定的方法進行替換,pad/ffill使用前面的值替換,backfill/bfill使用后面的值替換
limit 如果被替換的值有多個,最多替換多少個
s = pd.Series([1,2,'3',np.nan,'hello',np.nan]) print(s.replace(np.nan,method = 'bfill'))


0 1 1 2 2 3 3 hello 4 hello 5 NaN dtype: object
?
5.缺失值處理方法
①直接刪除空值(根據實際意義,如果缺失值占比<2%且不好填充,可考慮直接刪除)
②使用均值/中位數/眾數填充
③使用前值/后值填充
④插值,拉格朗日插值法
from scipy.interpolate import lagrange x = [3,6,9] y = [10,8,4] print(lagrange(x,y),type(lagrange(x,y))) print(lagrange(x,y)(15)) df = pd.DataFrame({'x':np.arange(20)}) df['y'] = lagrange(x,y)(df['x']) plt.plot(df['x'],df['y'],linestyle='--',marker = 'o') # -0.1111 x^2 + 0.3333 x + 10 <class 'numpy.poly1d'> # -10.000000000000004
?
s = pd.Series(np.random.rand(100)*100) s[3,6,33,56,45,66,67,80,90] = np.nan print('數據個數為%d'%len(s)) s_na = s[s.isnull()] print('缺失值個數為%d'%len(s_na)) print('缺失值占比%.2f%%'%(100*len(s_na)/len(s)))s_handle = s.fillna(s.median()) fig,axes = plt.subplots(1,4,figsize = (20,4)) s.plot.box(ax = axes[0],title = '數據分布') s.plot(kind = 'kde',linestyle = '--',ax = axes[1],title = '折線圖(默認刪除缺失值)') s_handle.plot(kind = 'kde',linestyle = '--',ax = axes[2],title = '折線圖(中位數填充缺失值)')def f(data,n,k = 5):y = data[list(range(n-k,n+1+k))]y = y[y.notnull()]return lagrange(y.index,list(y))(n)for i in range(len(s)):if s.isnull()[i]: s[i] = f(s,i)print(i,f(s,i))
?
二、異常值
異常值是指樣本中的個別值明顯偏離其余的樣本值,異常值也稱離群點,異常值的分析也稱為離群點的分析。
1.異常值鑒定
①3α原則
對于服從正態分布的樣本數據,通常認為 |樣本值-均值| >3倍標準差的樣本值為異常值。在實際工作中可自根據實際情況自定義這個倍數。
s = pd.Series(np.random.randn(1000)*100) u = s.mean() std = s.std() print('樣本均值為%.2f,標準差為%.2f'%(u,std)) p = stats.kstest(s,'norm',(u,std)).pvalue if p > 0.05:print('樣本服從正態分布')fig = plt.figure(figsize = (20,6)) ax1 = fig.add_subplot(1,2,1) s.plot(kind = 'kde',linestyle ='--',title = '原始數據密度曲線') plt.axvline(u+3*std,linestyle ='--',color = 'red') #u+3*std處繪制垂直線 plt.axvline(u-3*std,linestyle ='--',color = 'red') #u-3*std處繪制垂直線 unusual = s[abs(s-u) > 3*std] #異常值 s_clean = s[abs(s-u) <= 3*std] #非異常值 print('共有%d個異常值'%len(unusual)) ax2 = fig.add_subplot(1,2,2) plt.scatter(s_clean.index,s_clean.values,color = 'b') #非異常值用藍色表示 plt.scatter(unusual.index,unusual.values,color = 'r') #異常值用紅色表示 plt.title('正常值與異常值散點圖') # 樣本均值為-2.56,標準差為99.70 # 樣本服從正態分布 # 共有5個異常值
②箱型圖分析
箱型圖中,是將樣本值 > (q3+1.5*iqr)和樣本值<(q1-1.5*iqr)的樣本作為異常值。
s = pd.Series(np.random.randn(1000)*100)fig = plt.figure(figsize = (20,6)) ax1 = fig.add_subplot(121) s.plot.box(vert = False,label = '樣本數據箱型圖')des = s.describe() q1 = des['25%'] q3 = des['75%'] iqr = q3 - q1 ma = q3 + 1.5*iqr mi = q1 - 1.5*iqr unusual = s[(s>ma)|(s<mi)] s_clean = s[(s<ma)&(s>mi)] print('共有異常值%d個'%len(unusual))ax2 = fig.add_subplot(1,2,2) plt.scatter(s_clean.index,s_clean.values,color = 'b') #非異常值用藍色表示 plt.scatter(unusual.index,unusual.values,color = 'r') #異常值用紅色表示 plt.title('正常值與異常值散點圖')
?
2.異常值處理?
?刪除,或類似空值填充的方法修補。
?