Pandas-第六章缺失數據處理

 

目錄

一、缺失預測及其類型

二、缺失數據的運算與分組

三、填充與剔除

四、插值

線性插值

高級插值方法

interpolate中的限制參數

 


 

一、缺失預測及其類型

  1. 瞭解缺失值信息
    1. df.isna()  #或者df.列名.isna()
    2. df.info()
    3. df.notna()# 非空信息
    4. df[~df.列名.isna()] 對空取反操作,就是找非空
    5. 求缺失個數 df.isna().sum()
    6. 通過布爾值選擇缺失值所在行  df[df.列名.isna()]
    7. 選擇所有非缺失值列  df[df.notna().all(1)]   就是每一列都沒有缺失值,相當於尋找一條完整記錄。
  2. 三種缺失值符號
    1. np.nan   特點
      1. 浮點類型的數據,填充np.nan後會變爲object類型
      2. 修改布爾列表時,會改變列表類型,s=pd.Series([True,False],dtype='bool') s[1]=np.nan    dtype 爲float
      3. 對於布爾類型,如果事np.nan填充,值會變爲True    pd.Series([1,np.nan,3],dtype='bool')  True True True
      4. 整數列,如果存在缺失值就會變成浮點型pd.Series([1,2,3]) .dtype   int64    pd.Series([1,np.nan,3]).dtype   flost64
      5. 在numpy中,np.nan的類型爲float,可以通過type(np.nan)得到
      6. 在使用equals時,自動掠奪兩側全是空值的單元,df.equals(df)會得到True
      7. np.nan 不等於None
      8. np.nan 不等於0
      9. 自身不等於自身
      10. None
        1. None==None True
        2. 布爾值爲False
        3. 修改布爾值時,不改變數據類型
        4. 傳入數值後,自動變爲np.nan
        5. 傳入object類型時保持不變
        6. 使用equals函數時不會掠過,pd.Series([None]).equals(pd.Series([np.nan])
      11. NaT
        1. NaT是針對時間序列的缺失值,是pandas的內置類型,時序版本的np.nan與自己不等,使用equals是也會被跳過
        2. pd.Series([pd.Timestamp('20200202')]*5)  datetime64[ns]類型
        3. 爲datetime64添加空值,類型爲NaT  pd.NaT
        4. None NaT np.nan  在datetime類型中都是NaT
        5. pd.NaT==pd.NaT  false
        6. pd.NaT.equals(pd.NaT)
  3. Nullable類型與Na符號
    1. Nullable 是1.0新本中引入的,目的是爲了統一缺失值處理方法。
    2. 整型     s_new=pd.Series([1,2],dtype='Int64) 更新後的是使用大寫Int,在這個基礎上無論是np.nan None還是pd.NaT最後都是顯示<NA> 不改變之前的類型;
    3. 布爾   s_new=pd.Series([0,1],dtype='boolean') 不改變類型
    4. string  pd.Series(['dog','cat'],dtype='string) 添加缺失值,不會改變類型 <NA>
    5. Na的特性
      1. 邏輯運算
        1. 邏輯運算的結果根據是否依賴pd.NA的取值,依賴的話就是NA,不依賴的直接計算結果
      2. 算數運算和比較運算
        1. pd.NA**0   結果爲1
        2. 1**pd.NA 結果爲1
        3. 其他結果都是NA
        4. pd.NA+1  <NA>
        5. 'a'*pd.NA   <NA>
        6. pd.NA==pd.NA     <NA>
        7. pd.NA<2.5  <NA>
  4. convert_dtype方法
    1. pd.read_csv(''路徑').convert_dtypes()    把數據轉化爲Nullable類型

二、缺失數據的運算與分組

  1. 使用加法時缺失值爲0   s.sum()
  2. 使用乘法缺失值爲1        s.prod()
  3. 使用累加函數時缺失值自動略過    s.cumsum()
  4. 使用累乘函數缺失值自動掠過    s.cumprod()
  5. 默認比較和前一個的比值 s.pct_change()    第一個值之前沒有值,結果爲NaN  缺失值一列爲0
  6. groupby時自動忽略缺失值的組

三、填充與剔除

  1. fillna方法
    1. 值填充與向前後填充

      df.列名.fillna('missing')

      df.列名.fillna(method='ffill')

      df.列名.fillna(method='backfill')

  2. 填充中的對齊特性(不是特別懂)
    1. df_f=pd.DataFrame({'A':[1,3,np.nan],'B':[2,4,np.nan],'C':[3,5,np.nan]})
    2. df_f.fillna(df_f.mean())
    3. df_f.fillna(df_f.mean()[['A','B']])  返回的結果沒有c,不會被填充
  3. dropna方法 
    1. df.dropna(axis=0)  行
    2. df.dropna(axis=1) 列
    3. df.dropna(axis=1,how='all) 全部爲缺失值時去除
    4. df.dropna(axis=0,subset=['B','C'])  只爲BC兩列去除空值

四、插值

 s.interpolate(method='linear', axis=0, limit=None, inplace=False, limit_direction='forward', limit_area=None, downcast=None, **kwargs)
s=pd.Series([1,10,15,-5,-2,np.nan,np.nan,28])
s
out:
0     1.0
1    10.0
2    15.0
3    -5.0
4    -2.0
5     NaN
6     NaN
7    28.0
dtype: float64

 帶有多索引的只支持線性插值方法

  • method
    • linear :忽略索引,平等對待間隔。多值索引的唯一方法。
    • time 時間索引,和索引無關
    • pad 使用過去的值填充
  • s.interpolate(method='pad')
    Out[104]:
    0     1.0
    1    10.0
    2    15.0
    3    -5.0
    4    -2.0
    5    -2.0
    6    -2.0
    7    28.0
    • ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘spline’, ‘barycentric’, ‘polynomial’
    • ‘spline’和‘polynomial’需要添加order  
      df.interpolate(method='polynomial', order=5)
    • 'krogh', 'piecewise_polynomial', 'spline', 'pchip', 'akima'
    • 'from_derivatives'
  • limit 表示最多插入多少個
  • inplace
  • limit_direction 表示插值方向,默認前向
    • forward
    • backword
    • both
  • limit_area 表示插值區域

問題1:如何刪除缺失值佔比超過25%的列?

方法一:

             l=(df.isna().sum()/df.shape[0]).sort_values()>0.25   #先找到缺失值大於0.25的布爾值
              df.drop(columns=l[l].index)   l[l].index 找到男足條件的列

方法二:

             df.dropna(axis=1,thresh=df.shape[0]*(1-0.25))   thresh 保留至少n個不爲空的   使用axis選擇行或者列

問題2:什麼是Nullable類型?請談談爲什麼要引入這個設計?

            它是一種特殊的整型,是爲了解決pandas前幾個版本對於空值不統一的問題。

問題3  對於一份有缺失值的數據,可以採取哪些策略或方法深化對它的瞭解

  1. 判斷缺失值數量及特徵重要性再選擇策略;
  2. 對於不是特別重要的特徵且缺失數據量較大,考慮刪除特徵,dropna或者drop;
  3. 對於重要特徵,那麼考慮進行插值,除了本文所說的插值,也可以考慮使用決策樹等機器學習方法進行填補

 

練習

現有一份虛擬數據集,列類型分別爲string/浮點/整型,請解決如下問題:

  1. 請以列類型讀入數據,並選出C爲缺失值的行。
data=pd.read_csv('data/Missing_data_one.csv').convert_dtypes()
data[data.C.isna()]

	    A	  B	      C
1	not_NaN	0.700	<NA>
5	not_NaN	0.972	<NA>
11	not_NaN	0.736	<NA>
19	not_NaN	0.684	<NA>
21	not_NaN	0.913	<NA>

  1. 現需要將A中的部分單元轉爲缺失值,單元格中的最小轉換概率爲25%,且概率大小與所在行B列單元的值成正比。
    total_b = data['B'].sum()
    min_b = data['B'].min()
    data['A'] = pd.Series(list(zip(data['A'].values
                        ,data['B'].values))).apply(lambda x:x[0] if np.random.rand()>0.25*x[1]/min_b else np.nan)
    data.head()

     

    

現有一份缺失的數據集,記錄了36個人來自的地區、身高、體重、年齡和工資,請解決如下問題

  1. 統計各列缺失的比例並選出在後三列中至少有兩個非缺失值的
    #讀入數據
    d=pd.read_csv('data/Missing_data_two.csv').convert_dtypes()
    #查看各列缺失比例
    d.isnull().sum()/d.shape[0]
    #後三列至少有兩個非缺失值的行
    d[d.iloc[:,-3:].notna().sum(axis=1)>=2]

     

  2. 請結合身高列和地區列中的數據,對體重進行合理插值。
    d3 = d2.copy()
    for name,group in d2.groupby('地區'):
        d2.loc[group.index,'體重'] = group[['身高','體重']].sort_values(by='身高')['體重'].interpolate()
    d2['體重'] = d2['體重'].round(decimals=2)
    d2.head()
    
    
    
    
    
    def set_missing_w(data):
    
        # 把已有的數值型特徵取出來丟進Random Forest Regressor中
        df=data.copy()
        dis = {'A':'0','B':'1','C':'2'}
    
        df['地區'] = df['地區'].map(dis)
        w_df = df[['地區','身高', '體重']]
    
        # 分成已知體重和未知體重兩部分
        known_w = w_df[w_df.體重.notnull()]
        unknown_w = w_df[w_df.體重.isna()]
        # y即目標體重
        y = known_w.iloc[:, 2]
        # print(y)
        # X即特徵屬性值
        X = known_w.iloc[:, :2]
        # print(X)
        # fit到RandomForestRegressor之中
        rfr = RandomForestClassifier(random_state=0, n_estimators=2000, n_jobs=-1)
        rfr.fit(X, y.astype('int'))
    
      # 用得到的模型進行未知體重結果預測
        predictedAges = rfr.predict(unknown_w.iloc[:,:2])
        # 用得到的預測結果填補原缺失數據
        df.loc[ (df.體重.isnull()), '體重' ] = predictedAges 
        return df, rfr

     

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章