异常值处理
00 min
2024-5-13
在机器学习的数据预处理阶段, 经常需要对包含缺失值、离散值及重复数据的数据进行确认和必要的加工。在本章节中,将使用pandas对具有这些特性的数据进行提取,并对基本的处理方法进行讲解。

缺失值处理

所谓缺失值,是指数据中的某数据由于某些原因存在缺少的部分。在pandas中缺失值的默认值使用NaN(Not a Number)表示。

缺失值的数据类型

在pandas中,缺失值显示为NaN,其表示方法共有四种,np.nan、None,pd.NA。另外针对时间序列类型(datatime64类型)也同样有对应的缺失值,为pd.NaT
Python的浮点数中包含表示无穷大的inf。inf对象可以使用Python的内置函数float生成(float(”inf”)),也可以使用NumPy数组的常数numpy.inf生成。 pandas中提供了可以对各种设置进行变更的pd.options属性。其中,pd.options.mode.use_inf_as_na是一个是否将inf或-inf作为缺失值处理进行控制的设置项。默认为False,pandas不会将inf和负的inf作为缺失值处理,若为True,那么数组中(-)inf数据将会被看作为缺失值对其进行处理。

1、np.nan

  • 在NumPy中,常数np.nan是浮点数类型,因此如果当整形列中存在缺失值,整型列会转为浮点型列。
  • 缺失值NaN不等于任何值,任何值和NaN做等于比较都没空,包括自身

2、None

None也可以表示缺失值,在创建数组过程中传入None类型,会自动变成np.nan。None作为缺失值虽然也会改变整型的数据类型,但是None==None表达式返回的是True

3、pd.NA

pandas1.0以后的版本中引入了一个专门表示缺失值的标量pd.NA,它表示空整形、空布尔值、空字符,这个功能目前处于实验阶段。
开发者也注意到了这点,对于不同数据类型采取不同的缺失值表示会很乱。pd.NA就是为了统一而存在的。pd.NA的目标是提供一个缺失值指示器,可以在各种数据类型中一致使用(而不是np.nan、None或者NaT分情况使用)。用pd.NA表示缺失值,即使出现缺失值并不会改变原有列其他元素的数据类型

4、pd.NaT

包含数值类型的Series对象或列,通常都会变成NAN,但是将NaN添加到包含datetime64类型的列中,显示的是NaT。

缺失值计算

在处理包含缺失值的对象的运算中,NaN会传播,因此即使值中包含一个NaN,其运算结果也会是NaN
由于缺失值在计算过程中,犹如病毒一般会对数据产生不良影响,所以,接下来我们会讲解如何去确认缺失值,并对其做处理。

缺失值查看及判断

函数方法

  • DataFrame.isna()或Series.isna()
  • DataFrame.isnull()或Series.isnull()
    • 返回值:bool or array-like of bool,为NaN对应元素返回True,否则False
  • DataFrame.notna()或Series.notna()
  • DataFrame.notnull()或Series.notnull()
    • 返回值:bool or array-like of bool,为NaN对应元素返回False,否则True
📖
通常在获取到初始数据集之后,可以通过DataFrame.isna().sum() 来获取数据集中各字段的缺失值数量。

字符串方法

缺失值虽然不能做等号(==)判断,但是缺失值的字符串表达确实可以做相关操作的。(注:即便是字符串表达也不可以用is来判断)
  • nan —> ‘nan’
  • NaT —> ‘NaT’

缺失值删除

在很多情况下,机器学习使用的训练数据中是不允许包含缺失值的。因此,在开始训练模型前,必须对训练数据中缺失值进行处理。虽然对缺失值的处理方式有多种,但是没有哪一种方式是通用的。因此,需要根据所需处理数据的特性或目的决定使用哪种方式处理缺失值。
  • pd.DataFrame.dropna(axis=0, how=“any”, thresh=None, subset=None, inplace=False)
    • axis:{0 or 'index', 1 or 'columns'}, default 0;Determine if rows or columns which contain missing values are removed.
    • how:{'any', 'all'}, default 'any'
      • use with parameter axis
      • 'any' : If any NA values are present, drop that row or column.
      • 'all' : If all values are NA, drop that row or column.
    • thresh:int, optional;Require that many non-NA values. Cannot be combined with how.
    • subset:column label or sequence of labels, optional;Labels along other axis to consider, e.g. if you are dropping rows these would be a list of columns to include.
    • inplace:bool,default False;Whether to modify the DataFrame rather than creating a new one.
    • return:Series with NA entries dropped from it or None if ``inplace=True``
  • pd.Series(axis=0, inplace=False, how=None)
    • axis:{0 or 'index'}, Unused. Parameter needed for compatibility with DataFrame.
    • inplace:look above DataFrame
    • how:str, optional;Not in use. Kept for compatibility.

缺失值替换

在整体数据中,如果缺失值所占的比例较大时,最好的处理方式通常是将列或行删除;如果缺失值所占的比例较小时,通常是将确实值置换为其他值。替换缺失值的方法有两个:
  • pd.DataFrame.fillna
  • pd.DataFrame.interpolate

fillna方法

  • pd.DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
    • value:scalar, dict, Series, or DataFrame;将缺失值替换后的值
    • method:{'backfill', 'bfill', 'pad', 'ffill', None}, default None;替换方法,bfill or ffill
      • backfill / bfill:use next valid observation to fill gap.
      • ffill:use next valid observation to fill gap.
    • axis : {0 or 'index', 1 or 'columns'}
    • inplace:bool,default False;Whether to modify the DataFrame rather than creating a new one.
    • limit : int, default None;
      • If method is specified, this is the maximum number of consecutive NaN values to forward/backward fill. In other words, if there is a gap with more than this number of consecutive NaNs, it will only be partially filled. If method is not specified, this is the maximum number of entries along the entire axis where NaNs will be filled. Must be greater than 0 if not None.
    • downcast : dict, default None
      • A dict of item->dtype of what to downcast if possible, or the string 'infer' which will try to downcast to an appropriate equal type (e.g. float64 to int64 if possible).
在对DataFrame对象的缺失值进行填充的时候,可以结合pandas的聚合函数进行使用,即可以将DataFrame对象median、max、min、std等方法的返回值作为fillna的value参数,用作DataFrame对象缺失值的填充。至于用什么值填充缺失值,根据数据的特性不同,可使用的值也会不同。
 
在对Series对象或字典进行置换时,只能列队列进行填充,否则会报错。

interpolate方法

  • pd.DataFrame.interpolate(self: 'DataFrame', method='linear', axis = 0, limit=None, inplace=False, limit_direction=None, limit_area= None, downcast= None)
    • method:str, default 'linear';Interpolation technique to use. One of:
      • 'linear': Ignore the index and treat the values as equally spaced. This is the only method supported on MultiIndexes.
      • 'time': Works on daily and higher resolution data to interpolate given length of interval.
      • 'index', 'values': use the actual numerical values of the index.
      • 'pad': Fill in NaNs using existing values.
      • 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', 'spline', 'barycentric', 'polynomial': Passed to `scipy.interpolate.interp1d`. These methods use the numerical values of the index. Both 'polynomial' and 'spline' require that you also specify an `order` (int), e.g.``df.interpolate(method='polynomial', order=5)``.
      • 'krogh', 'piecewise_polynomial', 'spline', 'pchip', 'akima', 'cubicspline': Wrappers around the SciPy interpolation methods of similar names. See `Notes`.
      • 'from_derivatives': Refers to `scipy.interpolate.BPoly.from_derivatives` which replaces 'piecewise_polynomial' interpolation method in scipy 0.18.
    • axis : {{0 or 'index', 1 or 'columns', None}}, default None
    • limit : int, optional;Maximum number of consecutive NaNs to fill. Must be greater than 0.
    • inplace : bool, default False;Update the data in place if possible.
    • limit_direction : {{'forward', 'backward', 'both'}}, Optional; Consecutive NaNs will be filled in this direction.
      • If limit is specified
        • If 'method' is 'pad' or 'ffill', 'limit_direction' must be 'forward'.
        • If 'method' is 'backfill' or 'bfill', 'limit_direction' must be 'backwards'.
      • If 'limit' is not specified:
        • If 'method' is 'backfill' or 'bfill', the default is 'backward'
        • else the default is 'forward'
    • limit_area : {{`None`, 'inside', 'outside'}}, default None
      • 'inside': Only fill NaNs surrounded by valid values
      • 'outside': Only fill NaNs outside valid values (extrapolate).
    • downcast : optional, 'infer' or None, defaults None;Downcast dtypes if possible.
     
     

    重复值处理

    drop_duplicates()

    离散值处理