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

     

 

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