Python 玩转数据 18 - Pandas 数据清洗 处理缺失值 None NA NaN inf dropna fillna isin isnull

引言

本文主要介绍一下 Pandas 数据清洗,处理缺失值。更多 Python 进阶系列文章,请参考 Python 进阶学习 玩转数据系列

内容提要:

  1. 数据缺失的现实场景
  2. Python 中表示缺失值的对象
    ● None
    ● NaN
    ● NA
    ● 正负无穷 inf and -inf
  3. 处理缺失值
    ● 了解数据
    ● 定位缺失数据
    ● 处理缺失数据

数据缺失的现实场景

  1. 数据应用类别
    比如,患者生日,对女性来说是这个数据比较有参考意义,没有值提供的被认为是男性患者。
  2. 数据来源缺失
    比如用户调查数据,有部分用户拒绝提供数据,数据录入系统时由于数据转换被删除一部分数据。
  3. 数据无效
    输入格式不正确,或错误的数据(如,年龄 250 或 -5), 对这类数据就要处理成缺失数据

Python 中表示缺失值的对象

对象描述
NANot Available
NaNNot a Number
NonePythonic missing data, a Python object that can be used in arrays with data type object
infpositive infinity
-infnegative infinity

None

  1. None 一个 Python 对象
  2. 不可以用在任意的 NumPy 或 Pandas 数组里,只用于列表且数据类型是 Object。
  3. 默认 Pandas 会将 None 转换成 NAN
  4. 对包含 None 元素的数组进行计算(如: sum, min, max)会抛出 TypeError 异常。

在这里插入图片描述

NaN

  1. NaN 是一个特殊的浮点型值
  2. 带有 NaN 的值进行算术运算的结果是 NaN
  3. 可以用特殊的函数忽略 NaN: 如 np.nansum()

在这里插入图片描述
注意:NaN 是浮点型类型,如果用其它类型去访问它会抛出异常。
在这里插入图片描述

在这里插入图片描述

NA

  1. Pandas 遇到缺失对象会视为 NaN
  2. NumPy数组不能处理缺失对象,但能处理 NaN 值
import pandas as pd
import io
data_pd_na = '''Gender|Age|Weight
    M | 22 | 72.0
    F | 29 | 55.0
    M | 24 |
    F || 57.0
'''
df_na = pd.read_table (io.StringIO(data_pd_na), sep = '|')

# NumPy: Can NOT handle NA values
d2 = '''M  22  72.0
        F  29  
        M  24  78.0
        F  25  57.0
'''
data_np_na = io.StringIO(d2)

# Should produce a ValueError
np.loadtxt(data_np_na, 
           dtype={'names': ('Gender', 'Age', 'Color'), 
                  'formats': ('S1', 'i4', 'f4')})

在这里插入图片描述
NumPy能处理 NaN的值

# Missing values as NaN
d3 = '''M  22  72.0
        F  29  NaN
        M  24  78.0
        F  25  57.0
'''
data_np_nan = io.StringIO(d3)

# Should work with NaN missing values
np_array_nan = np.loadtxt(data_np_nan, 
                          dtype={'names': ('Gender', 'Age', 'Color'), 
                      'formats': ('S1', 'i4', 'f4')})

# an array of tuples
np.reshape (np.array (np_array_nan), (4,1))

在这里插入图片描述

# Missing values as NaN
d3 = '''1  22  1
        1  29  NaN
        1  24  1
        1  25  1
'''
data_np_nan = io.StringIO(d3)

# state explicitly to treat nan as floating point
np_array_nan = np.loadtxt(data_np_nan, dtype=np.float)

print (np_array_nan)
print (np_array_nan.shape) # 4-by-3 array

在这里插入图片描述
NaN 必须是浮点型类型,不然会抛错

# should fail if try to treat nan as int:
d4 = '''1  22  1
        1  29  NaN
        1  24  1
        1  25  1
'''
data_np_nan = io.StringIO(d4)

np_array_nan_int = np.loadtxt(data_np_nan, dtype=np.int)

在这里插入图片描述

正负无穷 inf and -inf

  1. 正负无穷的表示:
    ● float(“inf”) or float(“-inf”)
    ● np.inf, np.PINF, -np.inf, np.NINF
  2. 判断数字是否是正负无穷
    ● math 包的 math.isinf() 函数
    ● numpy 包的 np.isinf(), np.isposinf(), np.isneginf(), np.isfinite() 函数

正负无穷表示

import numpy as np

# positive infinity
p_inf = float("inf")
np_posinf = np.inf
np_posinf_1 = np.PINF

# negative infinity
n_inf = float("-inf")
np_neginf = -np.inf
np_neginf_1 = np.NINF


print("p_inf:{}".format(p_inf))
print("np_posinf:{}".format(np_posinf))
print("np_posinf_1:{}".format(np_posinf_1))
print("n_inf:{}".format(n_inf))
print("np_neginf:{}".format(np_neginf))
print("np_neginf_1:{}".format(np_neginf_1))

输出:

p_inf:inf
np_posinf:inf
np_posinf_1:inf
n_inf:-inf
np_neginf:-inf
np_neginf_1:-inf

判断是否是正负无穷:

import numpy as np
import pandas as pd
import io

x = np.array([-np.inf, 0., np.inf])
print("x:\n{}".format(np.isinf (x)))

data_pd_na = '''Gender|Age|Weight
    M | 22 | 72.0
    F || 55.0
    M | 24 |-inf
    F |inf| 57.0
'''
df = pd.read_table (io.StringIO(data_pd_na), sep = '|')
inf_df = df.isin ([np.inf, -np.inf])
# Remove rows with inf
no_inf_df = df[ ~df.isin([np.inf, -np.inf]).any(1) ]

print("inf_df:\n{}".format(inf_df))
print("no_inf_df:\n{}".format(no_inf_df))

在这里插入图片描述

Pandas: pd.set_options() to 处理 inf, -inf

通过 pd.set_option (‘mode.use_inf_as_na’, True) 将 inf 和 -inf 用 NaN 代替

import pandas as pd
import io

#pd.set_option?
# default is False
pd.set_option ('mode.use_inf_as_na', False)
pd_option = pd.get_option ('mode.use_inf_as_na')

data_pd_inf = '''Gender|Age|Weight
    M | 22 | 72.0
    F || 55.0
    M | 24 |-inf
    F |inf| 57.0
'''
df_inf = pd.read_table (io.StringIO(data_pd_inf), sep = '|')
print("options mode.use_inf_as_na:{}".format(pd_option))
print("df_inf:\n{}".format(df_inf))

# set mode.use_inf_as_na as true
pd.set_option ('mode.use_inf_as_na', True)
pd_option = pd.get_option ('mode.use_inf_as_na')

print("options mode.use_inf_as_na:{}".format(pd_option))
print("df_inf:\n{}".format(df_inf))

在这里插入图片描述

处理缺失值

步骤:

  1. 了解数据
  2. 定位缺失数据
  3. 处理缺失数据

下面通过一个例子来实战一把。

了解数据

通过 shape,columns,head() 等大概了解一下数据
在这里插入图片描述
在这里插入图片描述
describe() 了解一下统计信息,只支持数字类的统计,但是没有缺失数据的报告。
在这里插入图片描述

定位缺失数据

df.isin([np.nan, np.inf, -np.inf]) 判断数据是否缺失
在这里插入图片描述
df.info() 用来了解非缺失数据的数量
在这里插入图片描述
还可以通过下面几种方式更直观的了解缺失数据的数量。
df.isnull().sum()len(df.index) - df.count()
df.isnull().sum().sum() 和 *df.isnull().sum()/len(df)100
在这里插入图片描述

处理缺失数据

方法1:用 mask (Boolean) 数组过滤

● 用 df.isin([np.nan, np.inf, -np.inf]) 方法
● 用 df.any() 方法只要包含任意一个缺失的值
● 最后,用 布尔数组来进行切分

df [ ~df.isin([np.nan, np.inf, -np.inf]).any(1) ].head(5)
在这里插入图片描述

方法2:替换 inf 和 -inf 成 NaN, 然后选择 non-null 的行数据

df [ df.replace([np.inf, -np.inf], np.nan).notnull().all(axis=1) ].head(5)
在这里插入图片描述

方法3:替换 inf 和 -inf 成 NaN, 然后用 .dropna() 方法删除为空的数据

df.replace([np.inf, -np.inf], np.nan).dropna(axis=1).head(5)
在这里插入图片描述

方法4:用df.fillna(value=values) 将缺失的数据进行填充

values = {“NonD”:111, “Dream”:222, “Span”:333}
df.fillna(value = values).head()

df.fillna(555).head()
在这里插入图片描述

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值