手把手学爬虫第五弹——数据清洗与数据分析

什么是数据清洗

    数据清洗是指当我们通过爬虫获取数据以后对数据进行清洗,通过python对于数据中的空值、异常值、无效值进行修改删除。进而对清洗后的数据进行分析处理。

准备工作

    文章中我们将使用Jupyter Notebook进行数据处理。开始前需要在官网下载安装该环境。
    下载完成以后出现如下页面表示已经安装成功。
请添加图片描述

步入正题

使用Numpy处理数据

初识Numpy数组

    NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库.

创建Numpy数组

    创建一个Numpy的方式有很种,下面我们逐一进行了解测试.

  • 使用array()函数
    array()函既可以创建一维数组也可以创建二维数组。
import numpy as np
data1=np.array([1,2,3,4])
data1
data2=np.array([[1,2],[2,3],[4,5]])
data2

# ans:
array([1, 2, 3, 4])
array([[1, 2],
       [2, 3],
       [4, 5]])
  • 使用zeros()函数
    zerios()函数创建元素值都是0的数组
import numpy as np
np.zeros((3,5))

# ans:
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
  • 使用ones()函数
    ones()函数创建元素值都为1的数组
import numpy as np
np.ones((3,4))


# ans:
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
  • 使用empty()函数
import numpy as np
np.empty((5,2))

# ans:
array([[2.37663529e-312, 2.05833592e-312],
       [2.05833592e-312, 2.18565567e-312],
       [8.48798317e-313, 9.33678148e-313],
       [1.01855798e-312, 1.12465777e-312],
       [1.42421024e-306, 1.42410974e-306]])
  • 使用arange()函数
import numpy as np
np.arange(1,20,5)

# ans:
array([ 1,  6, 11, 16])
利用NumPy数组进行数据处理
  • 将条件逻辑转为数组运算
        NumPy的where()函数是三元表达式x if condition else y的矢量版本。
import numpy as np
arr1=np.array([1,5,7])
arr2=np.array([2,6,8])
arr3=np.array([True,False,True])
res = np.where(arr3,arr1,arr2)
res


# ans:
# 上面的代码的意思是根据arr3里的布尔值,
# 如果为True的话取arr1对应下标的数组元素,
# 如果为False的话取arr2对应下标的元素
array([1, 6, 7]);
  • 数组统计运算
arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr.mean() # 求平均值
4.5
arr.sum() # 求和
45
arr.min() # 求最小值
0
arr.max() # 求最大值
9
arr.argmin() # 求最小值的索引
0
arr.argmax() # 求最大值的索引
9
arr.cumsum() # 计算元素累加和
array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45], dtype=int32)
arr.cumprod()# 计算元素累计积
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

数据分析工具Pandas

初识Pandas

    Pandas 是一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析工具。Pandas 一个强大的分析结构化数据的工具集,基础是 Numpy(提供高性能的矩阵运算)。Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。

Pandas数据结构
Series

Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。

pandas.Series( data, index, dtype, name, copy)

参数说明:
data:一组数据(ndarray 类型)。
index:数据索引标签,如果不指定,默认从 0 开始。
dtype:数据类型,默认会自己判断。
name:设置名称。
copy:拷贝数据,默认为 False。

  • 创建方式1
import pandas as pd
obj=pd.Series([1,2,3,4,5])
obj

# ans:
# 使用构造方法创建Series对象
# 第一列是索引,第二列是数据
0    1
1    2
2    3
3    4
4    5
dtype: int64
  • 创建方式2
obj=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
obj

# ans:
# 使用构造方法创建Series对象时指定索引
# 第一列是索引,第二列是数据
a    1
b    2
c    3
d    4
e    5
dtype: int64
  • 创建方式3
dic_data = {'a':12,'b':14,'c':20}
obj = pd.Series(dic_data)
obj


# ans:
# 使用字典的方式创建
a    12
b    14
c    20
dtype: int64
DataFrame

    DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。

pandas.DataFrame( data, index, columns, dtype, copy)

参数说明:
data:一组数据(ndarray、series, map, lists, dict 等类型)。
index:索引值,或者可以称为行标签。
columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。
dtype:数据类型。
copy:拷贝数据,默认为 False。

  • 创建方式1
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
pd.DataFrame(arr_data)

# ans:
# 基于数组创建
	0	1	2
0	a	b	c
1	d	e	f

  • 创建方式2
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])


# ans:
# 指定索引创建
	N1	N2	N3
0	a	b	c
1	d	e	f
  • 根据索引获取值
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj['N2']   # 根据索引获取值

# ans:
0    b
1    e
Name: N2, dtype: object
  • 通过属性访问
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj.N2   # 通过属性访问

# ans:
0    b
1    e
Name: N2, dtype: object
  • 添加数据
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj['N4']=['f','g']  # 按索引添加数据
obj

# ans:
	N1	N2	N3	N4
0	a	b	c	f
1	d	e	f	g
  • 删除数据
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c'],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj['N4']=['f','g']
del obj['N2']    # del 删除数据
obj

# ans:
	N1	N3	N4
0	a	c	f
1	d	f	g
Pandas索引操作以及高级索引
索引对象

    Pandas中的索引都是index对象,又称为索引对象,该对象不可修改。
    索引对象不可修改的特性非常重要,这样使得多个数据结构之间能够很安全的共享index对象。

obj1=pd.Series(range(3),index=['a','b','c'])
obj2=pd.Series(['a','b','c'],index=obj1.index)
obj1.index is obj2.index

# ans:
True
重置索引

    reindex()方法作用是对原索引和新索引进行匹配,即,新索引有缘索引的数据,而原索引数据按照新索引排序。

index, columns:要符合的新标签/索引
method:None 、 backfill 、 bfill、pad、ffill、nearest可选
fill_value:可指定填充缺失值
limit:向前或向后填充的最大连续元素数

DataFrame.reindex(labels=None, index=None, columns=None, axis=None, method=None, copy=True, level=None, fill_value=nan, limit=None, tolerance=None)
obj=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
obj
​
obj1=obj.reindex(['a','b','c','x','y','z'])    # 重置索引
obj1


# ans:
a    1.0
b    2.0
c    3.0
x    NaN
y    NaN
z    NaN
dtype: float64
索引操作
  • Series索引操作
    Series的索引用法类似于Numpy数组的索引,但是Series的索引既可以通过索引的位置获取、也可以通过索引的名称获取。
obj=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
obj['b']	# 通过索引的名称获取
obj[1]  # 通过索引的位置获取

# ans:
2
  • 获取不连续的数据
obj=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
obj['b']

# ans:
b    2
d    4
f    6
dtype: int64
  • DataFrame的索引操作
    DataFrame结构既可以包含行索引、也可以包含列索引。其中,行索引是通过index属性进行获取,列索引是通过columns属性进行获取。
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj.N2


# ans:
0    b
1    e
Name: N2, dtype: object
  • DataFrame获取不连续的Series对象
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c',],['d','e','f']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3'])
obj[['N1','N3']]   # 不连续的Series对象

# ans:
	N1	N3
0	a	c
1	d	f
  • 索引高级操作
    loc:基于标签索引(索引名称),用于按标签选取数据。执行切片操作时,既包含起始索引又包含结束索引。
    iloc:基于位置索引(整数索引),用于按位置选取数据。执行切片操作时,只包含起始索引,不包含结束索引。
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c','d','e'],['d','e','f','g','h']])
obj=pd.DataFrame(arr_data, columns=['N1', 'N2', 'N3','N4','N5'])
obj.loc[:,['N2','N5']]  # 基于标签索引
# obj.iloc[:,[1,4]]    # 基于位置索引9999999999999999999999999999999999

# ans:
	N2	N5
0	b	e
1	e	h
数据排序
按索引排序
 sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None)

axis:0按照行名排序;1按照列名排序
level:默认None,否则按照给定的level顺序排列
ascending:默认True升序排列;False降序排列
inplace:默认False,否则排序之后的数据直接替换原来的数据
kind:排序方法

obj=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
obj.sort_index()  # 升序
obj.sort_index(ascending=False)


# ans:
# Series按索引升序排序
a    1
b    2
c    3
d    4
e    5
dtype: int64

# Series按索引降序排序
e    5
d    4
c    3
b    2
a    1
dtype: int64
import numpy as np
import pandas as pd
arr_data = np.array([['a','b','c'],['f','g','h'],['d','e','x']])
obj=pd.DataFrame(arr_data, index=[2,4,6])
# obj.sort_index()
obj.sort_index(ascending=False)

# ans
# DataFrame按索引升序排序
	0	1	2
2	a	b	c
4	f	g	h
6	d	e	x

# DataFrame按索引降序排序
	0	1	2
6	d	e	x
4	f	g	h
2	a	b	c

请添加图片描述

按值排序

参数即用法同按索引排序。

# Series按值排序

obj=pd.Series([1,4,3,8,5],index=['a','b','c','d','e'])
obj.sort_values()  # 升序

# ans:
a    1
c    3
b    4
e    5
d    8
dtype: int64

obj.sort_values(ascending=False) # 降序
d    8
e    5
b    4
c    3
a    1
dtype: int64

请添加图片描述

import numpy as np
import pandas as pd
arr_data = np.array([['a','b','y'],['f','g','h'],['d','e','x']])
obj=pd.DataFrame(arr_data, index=[2,4,6])
obj

# ans:
	0	1	2
2	a	b	y
4	f	g	h
6	d	e	x


obj.sort_values(by=2)   # 对索引为2的数据排序
	0	1	2
4	f	g	h
6	d	e	x
2	a	b	y
读写数据操作
读写CSV文件

Pandas为我们提供了read_csv读取CSV文件,该函数涉及参数较多,但是只有几个常用,具体的在这里我就不一一列举,感兴趣的可以看看这个博客read_csv()。下面写个实例看看怎么使用。

import pandas as pd
f = open(r'E:\python\pythonProject3\venv\Include\电影.csv',encoding='utf-8')
data = pd.read_csv(f)  # 读取csv文件,以‘,’作为分隔
data

请添加图片描述

读取txt文件
import pandas as pd
f = open(r'E:\python\pythonProject3\venv\Include\电影.txt',encoding='utf-8')
data = pd.read_table(f)  # 读取txt文件,以‘\t’作为分隔
data

请添加图片描述

读取Excel文件
import pandas as pd
data = pd.read_excel(r'E:\python\pythonProject3\venv\Include\ip.xlsx')  # 读取Excel文件,读取后转换成DataFrame对象
data

请添加图片描述

读取MySQL数据库
pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None)

sql:SQL命令字符串
con:连接sql数据库的engine,一般可以用SQLalchemy或者pymysql之类的包建立
index_col: 选择某一列作为index
coerce_float:非常有用,将数字形式的字符串直接以float型读入
columns:要选取的列。一般没啥用,因为在sql命令里面一般就指定要选择的列了

import pandas as pd
import MySQLdb
mysql_cn= MySQLdb.connect(host='localhost', port=3306,user='root', passwd='123456', db='movies')
df = pd.read_sql('select * from movice;', con=mysql_cn)    
mysql_cn.close()
df

请添加图片描述

读取mongodb数据库
# 读取mongodb同样需要安装驱动,先安装pymongo。
 
import pandas  as pd
import pymongo
 
client = pymongo.MongoClient(host='localhost',port=27017)
db = client.movies
collection = db.movie
data = pd.DataFrame(list(collection.find()))
data

请添加图片描述

数据预处理
空值和缺失值处理

在python里面一般空值使用None表示,缺失值使用NaN表示。Pandas中提供了一些用于检查或处理空值和缺失值的函数。

  • isnull()函数
        该函数的参数只有一个,表示检查空值的对象。
import pandas  as pd
from pandas import DataFrame,Series
from numpy import NaN
obj  = Series([1,None,NaN])
pd.isnull(obj)   # isnull()函数检查缺失值或者空值


# ans:
0     False
1     True
2     True       # 空值返回True
dtype: bool
  • notnull()函数
import pandas  as pd
from pandas import DataFrame,Series
from numpy import NaN
obj  = Series([1,None,NaN])
pd.notnull(obj)  # notnull()函数检查缺失值或者空值
 
 # ans:
0    True
1    False
2    False
dtype: bool    # 空值返回False
groupby()数据分组
  • 通过列名分组
import pandas  as pd
df=pd.DataFrame({"key1":['a','d','f','d','a','f'],
                "data":['2','5','6','8','9','2']})
obj=df.groupby(by="key1")   # 返回一个可迭代对象
for item in obj:
    print(item)

# ans:
# 结果为三个元组,所有key1相同的数据放在一起
# 三个数依次为 下标 键 值
('a',   key1 data
0    a    2
4    a    9)
('d',   key1 data
1    d    5
3    d    8)
('f',   key1 data
2    f    6
5    f    2)
  • 通过Series对象分组
import pandas  as pd
df=pd.DataFrame({"key1":['a','d','f','d','a','f'],
                 "key2":['A','D','F','D','A','F'],
                "data1":['2','5','6','8','9','2'],
                "data2":['4','7','3','6','8','2']})
se=pd.Series(['A','B','C',"D"])
obj=df.groupby(by=se)
for item in obj:
    print(item)


# ans:
('A',   key1 key2 data1 data2
0    a    A     2     4)
('B',   key1 key2 data1 data2
1    d    D     5     7)
('C',   key1 key2 data1 data2
2    f    F     6     3)
('D',   key1 key2 data1 data2
3    d    D     8     6)

# se将df对象分为A B C D四组
通过字典分组
import pandas  as pd
df=pd.DataFrame({"A":['a','d','f','d','a','f'],
                 "B":['A','D','F','D','A','F'],
                "C":['2','5','6','8','9','2'],
                "A":['2','5','6','8','9','2'],
                "D":['9','7','4','6','9','2'],
                "B":['4','7','3','6','8','2']})
map={"A":"第一组","B":"第二组","C":"第三组","D":"第四组"}
obj=df.groupby(by=map,axis=1)
for item in obj:
    print(item)


# ans:
('第一组',    A
0  2
1  5
2  6
3  8
4  9
5  2)
('第三组',    C
0  2
1  5
2  6
3  8
4  9
5  2)
('第二组',    B
0  4
1  7
2  3
3  6
4  8
5  2)
('第四组',    D
0  9
1  7
2  4
3  6
4  9
5  2)

总结

    今天的博客就到这了,本期我们一起学习了数据清洗与数据分析,因为这是一个很庞大的体系,所以我这里只列举了常用的一些,当然,也可能有遗漏的地方,后续我会继续添加补充。
    下一期我将带领大家学习爬虫的最后一弹,利用我们清洗完成的数据实现数据可视化。一起期待吧。
    如果你发现有问题或者有遗漏,欢迎指正~~

author: KK
time :2021年12月19日01:47:47
flag:11/30

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值