小白学 Python 数据分析(8):Pandas (七)数据预处理

人生苦短,我用 Pythonhtml

前文传送门:python

小白学 Python 数据分析(1):数据分析基础git

小白学 Python 数据分析(2):Pandas (一)概述程序员

小白学 Python 数据分析(3):Pandas (二)数据结构 Seriesgithub

小白学 Python 数据分析(4):Pandas (三)数据结构 DataFramesql

小白学 Python 数据分析(5):Pandas (四)基础操做(1)查看数据数据库

小白学 Python 数据分析(6):Pandas (五)基础操做(2)数据选择api

小白学 Python 数据分析(7):Pandas (六)数据导入数据结构

引言

上一篇咱们介绍了数据导入,在进行分析以前,还有一个比较重要的步骤就是数据的预处理,不少时候,咱们导入的数据质量并不高,会有不少不达标的数据。spa

这就和咱们天天作饭是同样的,买回来的菜总归会有一些不太好的部分,咱们须要在作饭以前对这些菜作一些预处理,将很差的部分处理掉。

常见的数据问题主要有缺失数据、重复数据以及异常数据这么几种,在开始进行数据分析以前,咱们须要先把这部分的数据处理掉。

缺失数据处理

缺失数据其实就是因为某些鲜为人知的缘由致使的部分数据为空,关注点不要放在鲜为人知的缘由是啥上哈,这种缘由简直多了去了,任何一位程序员都能举出来无数种例子。

对于这种部分为空的数据咱们一般有两种处理方式,一种是直接删除,还有一种是填充某种设定值。

固然,选用哪一种方式彻底是看具体的业务场景。

首先,第一步固然是把缺失的数据找出来, Pandas 找缺失数据可使用 info() 这个方法(这里选用的数据源仍是前面一篇文章所使用的 Excel ,小编这里简单的随机删除掉几个数据):

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")
print(df)

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
1      juejin       NaN         0      -2.0         1 2019-11-23 23:00:03
2        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
3      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
4      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
404      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
405    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
406    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
407      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[408 rows x 6 columns]

print(df.info())

# 输出结果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 408 entries, 0 to 407
Data columns (total 6 columns):
plantform      408 non-null object
read_num       406 non-null float64
fans_num       408 non-null int64
rank_num       407 non-null float64
like_num       408 non-null int64
create_date    408 non-null datetime64[ns]
dtypes: datetime64[ns](1), float64(2), int64(2), object(1)
memory usage: 19.2+ KB复制代码

从结果中能够看到,不为空的行数共计 408 行,而 read_num 这一行为 406 ,说明小编在这一列删掉了 2 个数据,在 rank_num 这一列删掉了 1 个数据。

咱们还可使用另外一个更加直观的方式来获取缺失的数据 isnull() ,若是是缺失的值,会返回 True ,若是不是则会返回 False :

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")
print(df.isnull())

# 输出结果
     plantform  read_num  fans_num  rank_num  like_num  create_date
0        False     False     False     False     False        False
1        False      True     False     False     False        False
2        False     False     False     False     False        False
3        False     False     False      True     False        False
4        False     False     False     False     False        False
..         ...       ...       ...       ...       ...          ...
403      False     False     False     False     False        False
404      False     False     False     False     False        False
405      False     False     False     False     False        False
406      False     False     False     False     False        False
407      False     False     False     False     False        False

[408 rows x 6 columns]复制代码

使用 isnull() 是比较直观,那么这里存在一个问题,就是好像数据显示不全啊,这种问题小 case ,只需一行代码轻松解决:

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

pd.set_option('display.max_rows', None)
print(df.isnull())复制代码

只须要对 pd 的显示设置下最大行数就好,结果稍微有点长,小编就不贴了。

缺失数据删除

咱们找到了缺失的数据,接下来就是对这部分数据进行删除操做了, Pandas 一样为咱们提供了一个现成的方法 dropna()

dropna() 这个方法会默认删除缺失数据的行,就是这一行只要有缺失数据,整行都会删除:

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.dropna())

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
2        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
4      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
5        csdn    2202.0       129       0.0        37 2019-11-22 23:00:01
7        csdn    1621.0        76       0.0        27 2019-11-21 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
404      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
405    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
406    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
407      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[405 rows x 6 columns]复制代码

能够看到,这里显示的行数只剩 405 行了,其中有 3 行有缺失的数据已经删除了。

在删除缺失行的时候还会有一种状况,就是整行数据全都缺失,咱们还能够只删除整行数据全缺失,若是只是有缺失值的数据保留,这时咱们能够用到 dropna() 的一个参数 how="any"

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.dropna(how="any"))

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
1      juejin       NaN         0      -2.0         1 2019-11-23 23:00:03
2        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
3      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
4      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
404      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
405    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
406    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
407      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[408 rows x 6 columns]复制代码

由于小编的数据没有整行缺失的,能够看到这里又打印了全部的数据。

固然, dropna() 同时支持各类条件删除,这里篇幅缘由小编就不一一列举了,有须要的同窗能够访问官方文档查看:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html 。

缺失数据填充

前面咱们介绍了缺失数据的删除,可是数据是很宝贵的,一般状况下确定不能作简单的删除操做,更多的时候咱们是但愿能填充咱们想要的默认值,这里咱们能够用到 fillna() 这个方法。

例如咱们在刚才的数据中补充 0 :

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.fillna(0))

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
1      juejin       0.0         0      -2.0         1 2019-11-23 23:00:03
2        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
3      cnblog     650.0         3       0.0         0 2019-11-22 23:00:15
4      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
404      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
405    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
406    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
407      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[408 rows x 6 columns]复制代码

上面的示例是将全部的缺失数据全都填充成了 0 ,可是若是咱们只想填充其中的一列数据呢?

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.fillna({'read_num': 10}))

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
1      juejin      10.0         0      -2.0         1 2019-11-23 23:00:03
2        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
3      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
4      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
404      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
405    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
406    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
407      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[408 rows x 6 columns]复制代码

为了便于区分,小编这里只补充了 read_num 这一列,将默认填充数值补充成了 10 。

重复数据处理

重复数据是指相同的记录有多条,这里通常简单的作删除操做。

Pandas 为咱们提供了 drop_duplicates() 方法用做重复值处理,默认会对全部值进行判断,而且会默认保留第一个值。

为了演示,小编将 Excel 中的数据第一行复制了一条。

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df)

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
1      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
2      juejin       NaN         0      -2.0         1 2019-11-23 23:00:03
3        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
4      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
..        ...       ...       ...       ...       ...                 ...
404    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
405      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
406    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
407    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
408      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[409 rows x 6 columns]

print(df.drop_duplicates())

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
2      juejin       NaN         0      -2.0         1 2019-11-23 23:00:03
3        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
4      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
5      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
404    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
405      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
406    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
407    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
408      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[408 rows x 6 columns]复制代码

能够看到第一个示例中共有 409 行数据,到了第二个结果,就只剩 408 行数据了。

这个示例是针对总体值进行判断的,咱们一样能够只针对某一列进行去重,只须要在 drop_duplicates() 这个方法中指明要判断的列便可:

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.drop_duplicates(subset='read_num'))

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
0      cnblog     215.0         0     118.0         0 2019-11-23 23:00:10
2      juejin       NaN         0      -2.0         1 2019-11-23 23:00:03
3        csdn    1652.0        69       0.0        24 2019-11-23 23:00:02
4      cnblog     650.0         3       NaN         0 2019-11-22 23:00:15
5      juejin     272.0         3     -23.0         1 2019-11-22 23:00:02
..        ...       ...       ...       ...       ...                 ...
403    cnblog     140.0         0      37.0         0 2020-02-20 23:00:08
404    juejin     212.0         0      -1.0         2 2020-02-20 23:00:02
405      csdn    1602.0         1       0.0         1 2020-02-20 23:00:01
406    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
408      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02

[342 rows x 6 columns]复制代码

能够看到这里只剩下了 342 行记录,固然对不对小编没有区验证,这个能够经过 sql 直接在数据库中作查询验证或者在 Excel 中使用去重进行验证(小编相信官方的 API 不会骗人)。

除了这些,还能够自定义删除重复项时保留哪一个,默认是保留第一个,也能够设置保留最后一个,还能够设置一个都不保留:

import pandas as pd

# 相对路径
df = pd.read_excel("result_data.xlsx")

print(df.drop_duplicates(subset='plantform', keep='last'))

# 输出结果
    plantform  read_num  fans_num  rank_num  like_num         create_date
406    cnblog      19.0         0      41.0         0 2020-02-21 23:00:05
407    juejin     125.0         1      -4.0         0 2020-02-21 23:00:02
408      csdn    1475.0         8       0.0         3 2020-02-21 23:00:02复制代码

小编这里选择经过 plantform 字段进行去重筛选,从行号上看应该对的,保留了最后三条数据。

keep 的值默认是 first ,也就是只保留第一个,除了 first , last 还有一个是 False ,它的含义是一个都不保留。

本篇的内容就到这里结束了,但愿各位同窗能多动动手,多敲敲代码,虽然这是学代码最笨的办法,但同时也是最有效的方法。

示例代码

老规矩,全部的示例代码都会上传至代码管理仓库 Github 和 Gitee 上,方便你们取用。

示例代码-Github

示例代码-Gitee

若是个人文章对您有帮助,请扫码关注下做者的公众号:获取最新干货推送:)
相关文章
相关标签/搜索