Pandas缺失值处理 | 轻松玩转Pandas(3)

教你学会 Pandas 不是个人目的,教你轻松玩转 Pandas 才是个人目的。我会经过一系列实例来带入 Pandas 的知识点,让你在学习 Pandas 的路上再也不枯燥。html

声明:我所写的轻松玩转 Pandas 教程都是免费的,若是对你有帮助,你能够持续关注我。python

Pandas基本功能详解 | 轻松玩转Pandas(2) 介绍了 Pandas 中经常使用的一些功能,使得咱们对 Pandas 的使用有了基本的了解。这一章节咱们来看下如何使用Pandas处理缺失值。正则表达式

# 导入相关库
import numpy as np
import pandas as pd
复制代码

什么是缺失值

在了解缺失值(也叫控制)如何处理以前,首先要知道的就是什么是缺失值?直观上理解,缺失值表示的是“缺失的数据”学习

能够思考一个问题:是什么缘由形成的缺失值呢?其实有不少缘由,实际生活中可能因为有的数据不全因此致使数据缺失,也有可能因为误操做致使数据缺失,又或者人为地形成数据缺失。人工智能

来看下咱们的示例吧。spa

index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name")

data = {
    "age": [18, 30, np.nan, 40, np.nan, 30],
    "city": ["BeiJing", "ShangHai", "GuangZhou", "ShenZhen", np.nan, " "],
    "sex": [None, "male", "female", "male", np.nan, "unknown"],
    "birth": ["2000-02-10", "1988-10-17", None, "1978-08-08", np.nan, "1988-10-17"]
}

user_info = pd.DataFrame(data=data, index=index)

# 将出生日期转为时间戳
user_info["birth"] = pd.to_datetime(user_info.birth)
user_info
复制代码
age birth city sex
name
Tom 18.0 2000-02-10 BeiJing None
Bob 30.0 1988-10-17 ShangHai male
Mary NaN NaT GuangZhou female
James 40.0 1978-08-08 ShenZhen male
Andy NaN NaT NaN NaN
Alice 30.0 1988-10-17 unknown

能够看到,用户 Tom 的性别为 None,用户 Mary 的年龄为 NAN,生日为 NaT。在 Pandas 的眼中,这些都属于缺失值,可使用 isnull()notnull() 方法来操做。code

user_info.isnull()
复制代码
age birth city sex
name
Tom False False False True
Bob False False False False
Mary True True False False
James False False False False
Andy True True True True
Alice False False False False

除了简单的能够识别出哪些是缺失值或非缺失值外,最经常使用的就是过滤掉一些缺失的行。好比,我想过滤掉用户年龄为空的用户,如何操做呢?cdn

user_info[user_info.age.notnull()]
复制代码
age birth city sex
name
Tom 18.0 2000-02-10 BeiJing None
Bob 30.0 1988-10-17 ShangHai male
James 40.0 1978-08-08 ShenZhen male
Alice 30.0 1988-10-17 unknown

丢弃缺失值

既然有缺失值了,常见的一种处理办法就是丢弃缺失值。使用 dropna 方法能够丢弃缺失值。htm

user_info.age.dropna()
复制代码
name
Tom      18.0
Bob      30.0
James    40.0
Alice    30.0
Name: age, dtype: float64
复制代码

Seriese 使用 dropna 比较简单,对于 DataFrame 来讲,能够设置更多的参数。对象

axis 参数用于控制行或列,跟其余不同的是,axis=0 (默认)表示操做行,axis=1 表示操做列。

how 参数可选的值为 any(默认) 或者 allany 表示一行/列有任意元素为空时即丢弃,all 一行/列全部值都为空时才丢弃。

subset 参数表示删除时只考虑的索引或列名。

thresh参数的类型为整数,它的做用是,好比 thresh=3,会在一行/列中至少有 3 个非空值时将其保留。

# 一行数据只要有一个字段存在空值即删除
user_info.dropna(axis=0, how="any")
复制代码
age birth city sex
name
Bob 30.0 1988-10-17 ShangHai male
James 40.0 1978-08-08 ShenZhen male
Alice 30.0 1988-10-17 unknown
# 一行数据全部字段都为空值才删除
user_info.dropna(axis=0, how="all")
复制代码
age birth city sex
name
Tom 18.0 2000-02-10 BeiJing None
Bob 30.0 1988-10-17 ShangHai male
Mary NaN NaT GuangZhou female
James 40.0 1978-08-08 ShenZhen male
Alice 30.0 1988-10-17 unknown
# 一行数据中只要 city 或 sex 存在空值即删除
user_info.dropna(axis=0, how="any", subset=["city", "sex"])
复制代码
age birth city sex
name
Bob 30.0 1988-10-17 ShangHai male
Mary NaN NaT GuangZhou female
James 40.0 1978-08-08 ShenZhen male
Alice 30.0 1988-10-17 unknown

填充缺失值

除了能够丢弃缺失值外,也能够填充缺失值,最多见的是使用 fillna 完成填充。

fillna 这名字一看就是用来填充缺失值的。

填充缺失值时,常见的一种方式是使用一个标量来填充。例如,这里我样有缺失的年龄都填充为 0。

user_info.age.fillna(0)
复制代码
name
Tom      18.0
Bob      30.0
Mary      0.0
James    40.0
Andy      0.0
Alice    30.0
Name: age, dtype: float64
复制代码

除了可使用标量来填充以外,还可使用前一个或后一个有效值来填充。

设置参数 method='pad'method='ffill' 可使用前一个有效值来填充。

user_info.age.fillna(method="ffill")
复制代码
name
Tom      18.0
Bob      30.0
Mary     30.0
James    40.0
Andy     40.0
Alice    30.0
Name: age, dtype: float64
复制代码

设置参数 method='bfill'method='backfill' 可使用后一个有效值来填充。

user_info.age.fillna(method="backfill")
复制代码
name
Tom      18.0
Bob      30.0
Mary     40.0
James    40.0
Andy     30.0
Alice    30.0
Name: age, dtype: float64
复制代码

除了经过 fillna 方法来填充缺失值外,还能够经过 interpolate 方法来填充。默认状况下使用线性差值,能够是设置 method 参数来改变方式。

user_info.age.interpolate()
复制代码
name
Tom      18.0
Bob      30.0
Mary     35.0
James    40.0
Andy     35.0
Alice    30.0
Name: age, dtype: float64
复制代码

替换缺失值

你们有没有想过一个问题:到底什么才是缺失值呢?你可能会奇怪说,前面不是已经说过了么,Nonenp.nanNaT 这些都是缺失值。可是我也说过了,这些在 Pandas 的眼中是缺失值,有时候在咱们人类的眼中,某些异常值咱们也会当作缺失值来处理。

例如,在咱们的存储的用户信息中,假定咱们限定用户都是青年,出现了年龄为 40 的,咱们就能够认为这是一个异常值。再好比,咱们都知道性别分为男性(male)和女性(female),在记录用户性别的时候,对于未知的用户性别都记为了 “unknown”,很明显,咱们也能够认为“unknown”是缺失值。此外,有的时候会出现空白字符串,这些也能够认为是缺失值。

对于上面的这种状况,咱们可使用 replace 方法来替换缺失值。

user_info.age.replace(40, np.nan)
复制代码
name
Tom      18.0
Bob      30.0
Mary      NaN
James     NaN
Andy      NaN
Alice    30.0
Name: age, dtype: float64
复制代码

也能够指定一个映射字典。

user_info.age.replace({40: np.nan})
复制代码
name
Tom      18.0
Bob      30.0
Mary      NaN
James     NaN
Andy      NaN
Alice    30.0
Name: age, dtype: float64
复制代码

对于 DataFrame,能够指定每列要替换的值。

user_info.replace({"age": 40, "birth": pd.Timestamp("1978-08-08")}, np.nan)
复制代码
age birth city sex
name
Tom 18.0 2000-02-10 BeiJing None
Bob 30.0 1988-10-17 ShangHai male
Mary NaN NaT GuangZhou female
James NaN NaT ShenZhen male
Andy NaN NaT NaN NaN
Alice 30.0 1988-10-17 unknown

相似地,咱们能够将特定字符串进行替换,如:将 "unknown" 进行替换。

user_info.sex.replace("unknown", np.nan)
复制代码
name
Tom        None
Bob        male
Mary     female
James      male
Andy        NaN
Alice       NaN
Name: sex, dtype: object
复制代码

除了能够替换特定的值以外,还可使用正则表达式来替换,如:将空白字符串替换成空值。

user_info.city.replace(r'\s+', np.nan, regex=True)
复制代码
name
Tom        BeiJing
Bob       ShangHai
Mary     GuangZhou
James     ShenZhen
Andy           NaN
Alice          NaN
Name: city, dtype: object
复制代码

使用其余对象填充

除了咱们本身手动丢弃、填充已经替换缺失值以外,咱们还可使用其余对象来填充。

例若有两个关于用户年龄的 Series,其中一个有缺失值,另外一个没有,咱们能够将没有的缺失值的 Series 中的元素传给有缺失值的。

age_new = user_info.age.copy()
age_new.fillna(20, inplace=True)
age_new
复制代码
name
Tom      18.0
Bob      30.0
Mary     20.0
James    40.0
Andy     20.0
Alice    30.0
Name: age, dtype: float64
复制代码
user_info.age.combine_first(age_new)
复制代码
name
Tom      18.0
Bob      30.0
Mary     20.0
James    40.0
Andy     20.0
Alice    30.0
Name: age, dtype: float64
复制代码

能够看到,用户信息中关于年龄的缺失值都使用 age_new 这个 Series 填充了。


想要学习更多关于人工智能的知识,请关注公众号:AI派

qrcode_for_gh_60cef389e81c_258.jpg

这里我将整篇文章的内容整理成了pdf,想要pdf文件的能够在公众号后台回复关键字:pandas03

更多Pandas知识见:轻松玩转Pandas

相关文章
相关标签/搜索