Pandas模块学习与使用
Pandas模块学习与使用
Pandas
是一个开源的,BSD许可的库,为Python (opens new window)编程语言提供高性能,易于使用的数据结构和数据分析工具。从 Numpy 和 Matplotlib 的基础上构建而来,享有数据分析“三剑客之一”的盛名(NumPy、Matplotlib、Pandas)。
Pandas概述
Pandas 这个名字来源于面板数据(Panel Data)与数据分析(data analysis)这两个名词的组合。在经济学中,Panel Data 是一个关于多维数据集的术语。
Pandas 是Python的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。经过多年不懈的努力,Pandas 离这个目标已经越来越近了。
Pandas 适用于处理以下类型的数据:
- 与 SQL 或 Excel 表类似的,含异构列的表格数据;
- 有序和无序(非固定频率)的时间序列数据;
- 带行列标签的矩阵数据,包括同构或异构型数据;
- 任意其它形式的观测、统计数据集, 数据转入 Pandas 数据结构时不必事先标记。
Pandas 的主要数据结构是 Series(一维数据)与 DataFrame (二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。对于 R 用户,DataFrame 提供了比 R 语言 data.frame 更丰富的功能。Pandas 基于 NumPy 开发,可以与其它第三方科学计算支持库完美集成。
Pandas 就像一把万能瑞士军刀,下面仅列出了它的部分优势 :
- 处理浮点与非浮点数据里的缺失数据,表示为
NaN
; - 大小可变:插入或删除 DataFrame 等多维对象的列;
- 自动、显式数据对齐:显式地将对象与一组标签对齐,也可以忽略标签,在 Series、DataFrame 计算时自动与数据对齐;
- 强大、灵活的分组(group by)功能:拆分-应用-组合数据集,聚合、转换数据;
- 把 Python 和 NumPy 数据结构里不规则、不同索引的数据轻松地转换为 DataFrame 对象;
- 基于智能标签,对大型数据集进行切片、花式索引、子集分解等操作;
- 直观地合并(merge)、连接(join)数据集;
- 灵活地重塑(reshape)、透视(pivot)数据集;
- 轴支持结构化标签:一个刻度支持多个标签;
- 成熟的 IO 工具:读取文本文件(CSV 等支持分隔符的文件)、Excel 文件、数据库等来源的数据,利用超快的 HDF5 格式保存 / 加载数据;
- 时间序列:支持日期范围生成、频率转换、移动窗口统计、移动窗口线性回归、日期位移等时间序列功能。
这些功能主要是为了解决其它编程语言、科研环境的痛点。处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas 是处理数据的理想工具。
其它说明:
- Pandas 速度很快。Pandas 的很多底层算法都用 Cython优化过。然而,为了保持通用性,必然要牺牲一些性能,如果专注某一功能,完全可以开发出比 Pandas 更快的专用工具。
- Pandas 是 statsmodels的依赖项,因此,Pandas 也是 Python 中统计计算生态系统的重要组成部分。
- Pandas 已广泛应用于金融领域。
Pandas安装
注意:Python核心团队计划在2020年1月1日停止支持Python 2.7。按照NumPy的计划,2018年12月31日之前的所有Pandas版本都仍支持Python 2(译者注:之后的版本将不再支持)。
2018年12月31日之前的最终版本将是支持Python 2的最后一个版本。已发布的软件包将继续在PyPI和conda上提供。
- 从 2019年1月1日 开始,所有版本都只支持Python 3。
从PyPI安装
$ pip install Pandas
用于解析HTML的可选依赖项
要使用顶级read_html() (opens new window)函数,需要以下一种库组合:
警告
如果安装BeautifulSoup4 (opens new window),必须安装lxml (opens new window)或html5lib (opens new window)或两个都安装。
read_html() (opens new window)不能只安装 BeautifulSoup4 (opens new window)。
强烈建议您阅读 HTML表解析之坑 (opens new window)。
它解释了有关上述三个库的安装和使用的问题。
Pandas内置数据结构
pandas在 ndarray 数组(NumPy 中的数组)的基础上构建出了两种不同的数据结构,分别是 Series(一维数据结构)DataFrame(二维数据结构)
- Series 是带标签的一维列表,这里的标签可以理解为索引,但这个索引并不局限于整数,它也可以是字符类型,比如 a、b、c 等;
- DataFrame 是一种表格型数据结构,它既有行标签,又有列标签。
维数 | 名称 | 描述 |
---|---|---|
1 | Series | 带标签的一维同构数组 |
2 | DataFrame | 带标签的,大小可变的,二维异构表格 |
一、pandas数据结构之 Series
Series 结构,也称 Series 序列,是 Pandas 常用的数据结构之一,它是一种类似于一维数组的结构,由一组数据值(value)和一组标签(索引)组成,其中标签与数据值之间是一一对应的关系。
Series 可以保存任何数据类型,比如整数、字符串、浮点数、Python 对象等,它的标签默认为整数,从 0 开始依次递增。
1、创建Series数据对象
Pandas 使用 Series() 函数来创建 Series 对象,通过这个对象可以调用相应的方法和属性,从而达到处理数据的目的.
# 语句定义格式
import pandas as pd
s=pd.Series( data, index, dtype, copy)
- 参数描述
参数名称 | 描述 |
---|---|
data | 输入的数据,可以是列表、字典、常量、ndarray 数组等。 |
index | 索引值必须是惟一的,如果没有传递索引,则默认为 np.arrange(n)。 |
dtype | dtype表示数据类型,如果没有提供,则会自动判断得出。 |
copy | 表示对 data 进行拷贝,默认为 False。 |
注:也可以使用数组、字典、标量值或者 Python 对象来创建 Series 对象。
1.1 创建一个空的Series对象
import pandas as pd
#输出数据为空
s = pd.Series([], dtype='float64')
print(s)
1.2 使用矩阵ndarray创建Series对象
ndarray 是 NumPy 中的数组类型,当 data 是 ndarry 时,传递的索引必须具有与数组相同的长度。假如没有给 index 参数传参,在默认情况下,索引值将使用是 range(n) 生成,其中 n 代表数组长度
import pandas as pd
import numpy as np
data = np.array(['a','b','c','d'])
s = pd.Series(data)
print (s)
没有传递任何索引,所以索引默认从 0 开始分配 ,其索引范围为 0 到
len(data)-1
,即 0 到 3。这种设置方式被称为“隐式索引”显示索引
import pandas as pd
import numpy as np
data = np.array(['a','b','c','d'])
#自定义索引标签(即显示索引)
s = pd.Series(data,index=[1001,1002,1003,1004])
print(s)
1.3 python字典dict创建Series对象
- 没有传递索引时
import pandas as pd
import numpy as np
dict1 = {'sj001': '小虎', 'sj002': '小杰', 'sj003': '小阳', 'sj004': '小超'}
pd2 = pd.Series(dict1)
print(pd2,type(pd2))
- 用
index
参数传递索引时
import pandas as pd
import numpy as np
# 取索引
dict1 = {'sj001': '小虎', 'sj002': '小杰', 'sj003': '小阳', 'sj004': '小超'}
# 如果一开始有索引,index的作用是取对应的索引,如果索引没有的话,值对应NaN
pd2 = pd.Series(dict1, index=['sj001', 'sj003', 'sj005'])
print(pd2, type(pd2))
小总结:
- 如果数据一开始没有索引,index的作用是加索引,如果超出值的个数,报错
- 如果数据一开始有索引,index的作用是取对应的索引,如果索引没有的话,值对应NaN
1.4 标量固定值创建
- 注意:如果是标量,如果没给索引值,就只有一个
import pandas as pd
import numpy as np
pd3 = pd.Series(100, index=[1001,1002,1003,1004])
print(pd3,type(pd3))
2、Series数据的使用
两种使用方式:
- 位置索引访问
- 索引标签访问
import pandas as pd
import numpy as np
# pd1 = pd.Series()
# print(pd1, type(pd1))
# 使用numpy中的矩阵创建
array1 = np.array([11, 22, 33, 44])
print(array1, type(array1))
# 重新给索引值
s1 = pd.Series(data=array1, index=[1001, 1002, 1003, 1004])
print(s1, type(s1))
print(s1[1002])
# print(s1[1]) # 报错
print("----------------------------------------------")
# 将python中字典数据转成Series对象
dict1 = {'1001':'小虎','1002':'张三','1003':'李四','1902':'王五'}
# 取出想要的索引
s2 = pd.Series(data=dict1, index=['1001','1003'])
print(s2, type(s2))
print(s2['1001']) # 使用本身字典中的键索引
print(s2[0]) # 也可以使用默认索引获取
print("----------------------------------------------")
list1 = [1001,1002,1003,1004]
s3=pd.Series(data='shujia', index=list1)
print(s3,type(s3))
print(s3[1001]) # 使用本身自定义的索引
# print(s3[0])
print("----------------------------------------------")
list1 = [1001,1002,1003,1004,1005]
s4=pd.Series(data=[11,22,33,44,55], index=list1)
print(s4,type(s4))
print(s4[1004]) # 使用本身自定义的索引
# print(s4[3])
通过验证,我们得到结论,只有字典既可以采用index参数的标签取值,也可以使用默认索引0-[n-1]取值
2.1 位置索引访问
这种访问方式与 ndarray 和 list 相同,使用元素自身的下标进行访问。索引计数从 0 开始,这表示第一个元素存储在第 0 个索引位置上,以此类推,就可以获得 Series 序列中的每个元素。
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(s[0]) #位置下标
注意:如果索引不是默认的话,需要我们使用定义的索引来获取,如果数据是列表这样的本身就有索引的数据的话,可以通过0-n的方式获取
- 通过切片的方式访问 Series 序列中的数据
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(s[:3]) # 不包括结束索引的值
- 获取最后三个元素
import pandas as pd
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(s[-3:])
2.2 索引标签访问(常用)
Series 类似于固定大小的 dict,把 index 中的索引标签当做 key,而把 Series 序列中的元素值当做 value,然后通过 index 索引标签来访问或者修改元素值。
- 使用索标签访问单个元素值
如果不存在会报错 KeyError: 'f'
import pandas as pd
s = pd.Series([6,7,8,9,10],index = ['a','b','c','d','e'])
print(s['a'])
- 使用索引标签访问多个元素值
import pandas as pd
s = pd.Series([6,7,8,9,10],index = ['a','b','c','d','e'])
print(s[['a','c','d']])
3、Series常用属性
名称 | 属性 |
---|---|
axes | 以列表的形式返回所有行索引标签。 |
dtype | 返回对象的数据类型。 |
ndim | 返回输入数据的维数。 |
size | 返回输入数据的元素数量。 |
values | 以 ndarray 的形式返回 Series 对象。 |
index | 返回一个RangeIndex对象,用来描述索引的取值范围。 |
empty | 返回一个空的 Series 对象。 |
- 随机创建一个Series数据
import pandas as pd
import numpy as np
array2 = np.array([11, 22, 33, 44, 55])
pd3 = pd.Series(array2, index=[1001, 1002, 1003, 1004, 1005])
# print(pd3,type(pd3))
-
axes
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(5))
print ("所有行索引标签:")
print(s.axes)
-
dtype
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(5))
print ("数据类型:")
print(s.dtype)
-
empty
返回一个布尔值,用于判断数据对象是否为空
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(5))
print("是否为空对象?")
print (s.empty)
-
ndim
查看序列的维数。因为Series 是一维数据结构,因此它始终返回 1。
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(5))
print (s)
print (s.ndim)
-
size 返回 Series 对象的大小(长度)
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(3))
print (s)
#series的长度大小
print(s.size)
-
values
以数组的形式返回 Series 对象中的数据。
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(6))
print(s)
print("输出series中数据")
print(s.values) # 返回的是一维的矩阵
-
index
用来查看 Series 中索引的取值范围
#显示索引
import pandas as pd
s=pd.Series([1,2,5,8],index=['a','b','c','d'])
print(s.index)
#隐式索引
s1=pd.Series([1,2,5,8])
print(s1.index)
4、Series常用函数
-
head() 默认显示前5条
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(8))
print (s)
#返回前三行数据
print (s.head(3))
-
tail() 取后几条 默认取后5条
import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(4))
#原series
print(s)
#输出后两行数据
print (s.tail(2))
-
isnull() 和notnull()
- isnull():如果为值不存在或者缺失,则返回 True。
- notnull():如果值不存在或者缺失,则返回 False。
import pandas as pd
#None代表缺失数据
s=pd.Series([1,2,5,None])
print(pd.isnull(s)) #是空值返回True
print(pd.notnull(s)) #空值返回False
二、pandas数据结构之DataFrame
DataFrame 一个表格型的数据结构,既有行标签(index),又有列标签(columns),它也被称异构数据表,所谓异构,指的是表格中每列的数据类型可以不同,比如可以是字符串、整型或者浮点型等。
表格中展示了某个数据团队个人信息和绩效成绩的相关数据。数据以行和列形式来表示,其中每一列表示一个属性,而每一行表示一个条目的信息。
Column | Type |
---|---|
name | String |
age | integer |
gender | String |
clazz | String |
score | Float |
DataFrame 的每一行数据都可以看成一个 Series 结构,只不过,DataFrame 为这些行中每个数据值增加了一个列标签。因此 DataFrame 其实是从 Series 的基础上演变而来。
- DataFrame 自带行标签索引,默认为“隐式索引”即从 0 开始依次递增,行标签与 DataFrame 中的数据项一一对应。上述表格的行标签从 0 到 3
1、DataFrame特点(6点)
- DataFrame 每一列的标签值允许使用不同的数据类型;
- DataFrame 是表格型的数据结构,具有行和列;
- DataFrame 中的每个数据值都可以被修改。
- DataFrame 结构的行数、列数允许增加或者删除;
- DataFrame 有两个方向的标签轴,分别是行标签和列标签;
- DataFrame 可以对行和列执行算术运算。
2、创建DataFrame对象
import pandas as pd
pd.DataFrame( data, index, columns, dtype, copy)
参数说明
参数名称 | 说明 |
---|---|
data | 输入的数据,可以是 ndarray,series,list,dict,标量以及一个 DataFrame。 |
index | 行标签,如果没有传递 index 值,则默认行标签是 np.arange(n),n 代表 data 的元素个数。 |
columns | 列标签,如果没有传递 columns 值,则默认列标签是 np.arange(n)。 |
dtype | dtype表示每一列的数据类型。 |
copy | 默认为 False,表示复制数据 data。 |
2.1 创建空的DataFrame对象
import pandas as pd
df = pd.DataFrame()
print(df)
2.2 列表创建DataFame对象
-
使用单一列表列表来创建一个 DataFrame
import pandas as pd data = [1,2,3,4,5] df = pd.DataFrame(data) print(df)
-
使用嵌套列表创建 DataFrame
import pandas as pd list2 = [['小白', 18, '男'], ['小黑', 17, '男'], ['小红', 17, '女']] df3 = pd.DataFrame(list2) print(df3, type(df3)) # 嵌套列表列表中的每一个小列表,表示的是每一行
-
指定数值元素的数据类型为 float
import pandas as pd data = [['xiaohu',18],['xiaoge',17],['fengfeng',15]] df = pd.DataFrame(data,columns=['Name','Age'],dtype=float) # 虽然被弃用 但是目前3.7.9也可以用 建议不加dtype=float,但是要在赋值的时候,确定数据类型 print(df)
-
字典嵌套列表创建(常用的)
data 字典中,键对应的值的元素长度必须相同(也就是列表长度相同)。如果传递了索引,那么索引的长度应该等于数组的长度;如果没有传递索引,那么默认情况下,索引将是 range(n),其中 n 代表数组长度。
- 字典中的键,作为DataFrame中的列名存在,后面值作为一列存在
{ k1:[], k2:[], k3:[] } k1 k2 k3 0 x x x 1 x x x import pandas as pd data = {'Name':['xiaohu', 'xiaoge', 'fengfeng', 'tongge'],'Age':[18,17,15,16]} df = pd.DataFrame(data) print(df)
-
加自定义的行标签
import pandas as pd data = {'Name':['xiaohu', 'xiaoge', 'fengfeng', 'tongge'],'Age':[18,17,15,16]} df = pd.DataFrame(data, index=['1001','1002','1003','1004']) print(df)
-
列表嵌套字典创建DataFrame对象
列表嵌套字典可以作为输入数据传递给 DataFrame 构造函数。默认情况下,字典的键被用作列名。
import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df = pd.DataFrame(data) print(df)
注意: 如果其中某个元素值缺失,也就是字典的 key 无法找到对应的 value,将使用 NaN 代替。
-
使用字典嵌套列表以及行、列索引表创建一个 DataFrame 对象。
这种方式中的columns参数指的是取出对应的列转成DataFrame 对象。
import pandas as pd data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}] df1 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b']) df2 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b1']) print(df1) print(df2)
b1 在字典键中不存在,所以对应值为 NaN。
-
Series创建DataFrame对象
传递一个字典形式的 Series,从而创建一个 DataFrame 对象,其输出结果的行索引是所有 index 的合集。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df)
3、DataFrame使用与操作
3.1 列索引操作DataFrame
DataFrame 可以使用列索(columns index)引来完成数据的选取、添加和删除操作
-
列索引选取数据列
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df['one']) # 直接取的是列名
-
列索引添加数据列
import pandas as pd d = {'Name' : pd.Series(['xiaohu1', 'xiaohu2', 'xiaohu3','xiaohu4'], index=['a', 'b', 'c','d']), 'math' : pd.Series([89, 92, 91], index=['a', 'b', 'c'])} df = pd.DataFrame(d) #使用df['列']=值,插入新的数据列 df['english']=pd.Series([67,78,79,99],index=['a','b','c','d']) print(df) #将已经存在的数据列做相加运算 df['zongfen']=df['math']+df['english'] # NaN与任意一个值相加,结果依旧是NaN print(df)
-
使用 insert() 方法插入新的列
import pandas as pd info=[['xiaohu',18],['xiaoge',19],['fengfeng',17]] df=pd.DataFrame(info,columns=['name','age']) print(df) #注意是column参数 #数值1代表插入到columns列表的索引位置 df.insert(1,column='score',value=[91,90,75]) print(df)
-
列索引删除数据列
通过 del 和 pop() 都能够删除 DataFrame 中的数据列。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 'three' : pd.Series([10,20,30], index=['a','b','c'])} df = pd.DataFrame(d) print(df) #使用del删除 del df['one'] print(df) #使用pop方法删除 df.pop('two') # 将删除的列封装成Series对象进行返回 print (df)
3.2 行索引操作DataFrame
-
标签索引选取
可以将行标签传递给 loc 函数
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print(df.loc['b'])
注意:返回的是.Series类型
-
整数索引选取
通过将数据行所在的索引位置传递给 iloc 函数,也可以实现数据行选取
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) print (df.iloc[2])
-
切片操作多行选取
您也可以使用切片的方式同时选取多行。
import pandas as pd d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])} df = pd.DataFrame(d) #左闭右开 print(df[2:4])
-
添加数据行
使用 append() 函数,可以将新的数据行添加到 DataFrame 中,该函数会在行末追加数据行。
import pandas as pd df = pd.DataFrame([[1, 2], [3, 4]], columns = ['a','b']) df2 = pd.DataFrame([[5, 6], [7, 8]], columns = ['a','c']) #在行末追加新数据行 df = df.append(df2) print(df)
-
删除数据行
您可以使用行索引标签,从 DataFrame 中删除某一行数据。如果索引标签存在重复,那么它们将被一起删除。
import pandas as pd df = pd.DataFrame([[1, 2], [3, 4]], columns = ['a','b']) df2 = pd.DataFrame([[5, 6], [7, 8]], columns = ['a','b']) df = df.append(df2) print(df) #注意此处调用了drop()方法 df = df.drop(0) # 根据索引值删除 print (df)
4、常用属性和方法汇总
DataFrame 的属性和方法,与 Series 相差无几
名称 | 属性 方法描述 |
---|---|
T | 行和列转置。 |
axes | 返回一个仅以行轴标签和列轴标签为成员的列表。 |
dtypes | 返回每列数据的数据类型。 |
empty | DataFrame中没有数据或者任意坐标轴的长度为0,则返回True。 |
ndim | 轴的数量,也指数组的维数。 |
shape | 返回一个元组,表示了 DataFrame 维度。 |
size | DataFrame中的元素数量。 |
values | 使用 numpy 数组表示 DataFrame 中的元素值。 |
head() | 返回前 n 行数据。 |
tail() | 返回后 n 行数据。 |
shift() | 将行或列移动指定的步幅长度 |
数据创建
import pandas as pd
import numpy as np
d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']),
'years':pd.Series([5,6,15,28,3,19,23]),
'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])}
#构建DataFrame
df = pd.DataFrame(d)
#输出series
print(df)
-
T 转置
返回 DataFrame 的转置,也就是把行和列进行交换。
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #输出series print(df.T)
-
axes
返回一个行标签、列标签组成的列表
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #输出series print(df.axes)
-
dtypes 查看字段类型
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #输出行、列标签 print(df.dtypes)
-
empty
返回一个布尔值,判断输出的数据对象是否为空,若为 True 表示对象为空
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #判断输入数据是否为空 print(df.empty)
-
ndim
返回数据对象的维数。DataFrame 是一个二维数据结构
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #DataFrame的维度 print(df.ndim)
-
shape
返回一个代表 DataFrame 维度的元组。返回值元组 (a,b),其中 a 表示行数,b 表示列数
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #DataFrame的形状 print(df.shape)
-
size
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #DataFrame的中元素个数 print(df.size)
-
values
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #DataFrame的数据 print(df.values)
-
head()和tail()查看数据 默认还是取5条
import pandas as pd import numpy as np d = {'Name':pd.Series(['python编程大全','hadoop基础',"hive进阶",'spark基础','flink进阶','mysql从入门到成神','java之路']), 'years':pd.Series([5,6,15,28,3,19,23]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8])} #构建DataFrame df = pd.DataFrame(d) #获取前3行数据 print(df.head(3)) #获取后2行数据 print(df.tail(2))
-
shift()移动行或列
语法格式:
DataFrame.shift(periods=1, freq=None, axis=0)
参数名称 说明 peroids 类型为int,表示移动的幅度,可以是正数,也可以是负数,默认值为1。 freq 日期偏移量,默认值为None,适用于时间序。取值为符合时间规则的字符串。 axis 如果是 0 或者 “index” 表示上下移动,如果是 1 或者 “columns” 则会左右移动。 fill_value 该参数用来填充缺失值。 - peroids
import pandas as pd info= pd.DataFrame({'a_data': [40, 28, 39, 32, 18], 'b_data': [20, 37, 41, 35, 45], 'c_data': [22, 17, 11, 25, 15]}) #移动幅度为3 info.shift(periods=3)
- fill_value 参数填充 DataFrame 中的缺失值
import pandas as pd info= pd.DataFrame({'a_data': [40, 28, 39, 32, 18], 'b_data': [20, 37, 41, 35, 45], 'c_data': [22, 17, 11, 25, 15]}) #移动幅度为3 print(info.shift(periods=3)) #将缺失值和原数值替换为52 info.shift(periods=3,axis=1,fill_value= 52) print('---------------') info2 = info.shift(periods=3) info3 = info2.fillna('丢啦') # 只填充NaN值 print(info3)
三、Pandas数学分析(描述性统计)
常用函数如下:
函数名称 | 描述说明 |
---|---|
count() | 统计某个非空值的数量。 |
sum() | 求和 |
mean() | 求均值 |
median() | 求中位数 |
mode() | 求众数 |
std() | 求标准差 |
min() | 求最小值 |
max() | 求最大值 |
abs() | 求绝对值 |
prod() | 求所有数值的乘积。 |
cumsum() | 计算累计和,axis=0,按照行累加;axis=1,按照列累加。 |
cumprod() | 计算累计积,axis=0,按照行累积;axis=1,按照列累积。 |
corr() | 计算数列或变量之间的相关系数,取值-1到1,值越大表示关联性越强。 |
在 DataFrame 中,使用聚合类方法时需要指定轴(axis)参数。
常用函数
- 对行操作,默认使用 axis=0 或者使用 “index”
- 对列操作,默认使用 axis=1 或者使用 “columns”
axis=0 表示按垂直方向进行计算,而 axis=1 则表示按水平方向。
数据创建
import pandas as pd
import numpy as np
#创建字典型series结构
d = {'Name':pd.Series(['小虎','小杰','小龙','小明','小赵','小李','小陈',
'老李','老王','小唐','老覃','小阳']),
'Age':pd.Series([25,26,25,23,18,29,18,14,19,20,24,21]),
'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])
}
df = pd.DataFrame(d)
print(df)
-
sum()求和
在默认情况下,返回 axis=0 的所有值的和
import pandas as pd import numpy as np #创建字典型series结构 d = {'Name':pd.Series(['小虎','小杰','小龙','小明','小赵','小李','小陈', '老李','老王','小唐','老覃','小阳']), 'Age':pd.Series([25,26,25,23,18,29,18,14,19,20,24,21]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } df = pd.DataFrame(d) #默认axis=0或者使用sum("index") print(df.sum()) #也可使用sum("columns")或sum(1) print(df.sum(axis=1))
-
mean()求均值
import pandas as pd import numpy as np #创建字典型series结构 d = {'Name':pd.Series(['小虎','小杰','小龙','小明','小赵','小李','小陈', '老李','老王','小唐','老覃','小阳']), 'Age':pd.Series([25,26,25,23,18,29,18,14,19,20,24,21]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } df = pd.DataFrame(d) print(df.mean())
-
std()求标准差
import pandas as pd import numpy as np #创建字典型series结构 d = {'Name':pd.Series(['小虎','小杰','小龙','小明','小赵','小李','小陈', '老李','老王','小唐','老覃','小阳']), 'Age':pd.Series([25,26,25,23,18,29,18,14,19,20,24,21]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } df = pd.DataFrame(d) print(df.std())
注意,平均数相同的两组数据,标准差未必相同。
-
describe() 函数显示与 DataFrame 数据列相关的统计信息摘要。
import pandas as pd import numpy as np #创建字典型series结构 d = {'Name':pd.Series(['小虎','小杰','小龙','小明','小赵','小李','小陈', '老李','老王','小唐','老覃','小阳']), 'Age':pd.Series([25,26,25,23,18,29,18,14,19,20,24,21]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65]) } df = pd.DataFrame(d) #求出数据的所有描述信息 print(df.describe())
四、Pandas csv读写文件
xxx.csv 列之间的默认分隔符是英文逗号
xxx.xlsx 记事本打开是看不懂的
read_csv()读文件
# 基本语法如下,pd为导入Pandas模块的别名:
pd.read_csv(filepath_or_buffer: Union[str, pathlib.Path, IO[~AnyStr]],
sep=',', delimiter=None, header='infer', names=None, index_col=None,
usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True,
dtype=None, engine=None, converters=None, true_values=None,
false_values=None, skipinitialspace=False, skiprows=None,
skipfooter=0, nrows=None, na_values=None, keep_default_na=True,
na_filter=True, verbose=False, skip_blank_lines=True,
parse_dates=False, infer_datetime_format=False,
keep_date_col=False, date_parser=None, dayfirst=False,
cache_dates=True, iterator=False, chunksize=None,
compression='infer', thousands=None, decimal: str = '.',
lineterminator=None, quotechar='"', quoting=0,
doublequote=True, escapechar=None, comment=None,
encoding=None, dialect=None, error_bad_lines=True,
warn_bad_lines=True, delim_whitespace=False,
low_memory=True, memory_map=False, float_precision=None)
一般情况下,会将读取到的数据返回一个DataFrame,当然按照参数的要求会返回指定的类型。
参数说明
传参路径
filepath_or_buffer为第一个参数,没有默认值,也不能为空,根据Python的语法,第一个参数传参时可以不写参数名。可以传文件路径:
# 支持文件路径或者文件缓冲对象
# 本地相对路径
pd.read_csv('data/demo1.csv') # 注意目录层级
pd.read_csv('demo1.csv') # 如果文件与代码文件在同一目录下
pd.read_csv('data/my/my.data') # CSV文件的扩展名不一定是.csv
# 本地绝对路径
pd.read_csv('C:\\Users\\xiaohu\\Desktop\\demo1.csv')
# 使用URL
pd.read_csv('https://www.xiaohu.com/file/data/dataset/demo1.csv')
可以传数据字符串,即CSV中的数据字符以字符串形式直接传入:
from io import StringIO
data = ('col1,col2,col3\n'
'a,b,1\n'
'a,b,2\n'
'c,d,3')
pd.read_csv(StringIO(data))
pd.read_csv(StringIO(data), dtype=object)
分隔符
# sep参数是字符型的,代表每行数据内容的分隔符号,默认是逗号,另外常见的还有制表符(\t)、空格等,根据数据的实际情况传值。
# 数据分隔符默认是逗号,可以指定为其他符号
pd.read_csv(data, sep='\t') # 制表符分隔tab
pd.read_table(data) # read_table 默认是制表符分隔tab
pd.read_csv(data, sep='|') # 制表符分隔tab
pd.read_csv(data,sep="(?<!a)\|(?!1)", engine='python') # 使用正则表达式
data = pd.read_csv("C:\\Users\\xiaohu\\Desktop\\demo1.csv", encoding="gbk", sep=",|:|;", engine="python", header=0)
print(data)
index_col
这个参数是用来决定读进来的数据哪一列做索引的。
这个参数的缺省值是False,就是什么都不做的意思。
咱们来指定第一列看看,第一列在Python里被标做1:(从0开始)
data = pd.read_csv("C:\\Users\\xiaohu\\Desktop\\demo1.csv", encoding="gbk", index_col=1)
usecols
这个参数可以指定你从文件中读取哪几列。比如这样:
data = pd.read_csv("C:\\Users\\xiaohu\\Desktop\\demo1.csv", encoding="gbk", usecols=[2,3])
nrows
指定读取记录多少行。
data = pd.read_csv("C:\\Users\\xiaohu\\Desktop\\demo1.csv", encoding="gbk", nrows=10)
to_csv()写文件
将Dataframe保存位一个csv文件
df.to_csv("a.csv")
写CSV的函数to_csv()参数很多,选几个比较重要的给大家说一下。
参数说明
index
缺省index=True,就是上面看到的a到d是索引号。如果你不加这个参数,写文件时会连带索引号一起写入。
df.to_csv("a.csv", index=False)
columns
按指定的列写入文件,我在下面只写入文件1列,有意去掉了读操作。
df.to_csv("a.csv", index=False,columns=['two'])
encoding
encoding主要是为了兼容Python2的一些中文操作。
大家知道由于计算机的发展历史,中文以及中文语系(包括日文、韩文等)并没有西方字母排列的那么规范。导致我们在不同的系统环境、不同的编程语言下都有可能会生成编码不一样的中文文件来。
这样的文件打印出来没差别,但作为电子文件保留下来,若干年后的人在打开时,会由于不知道中文用的是哪套编码而出现乱码。乱码不仅仅是简体和繁体中文的问题。
建议在写文件时最好加入encoding参数,并制定编码为“utf-8”,这也是目前全球应用最广泛的编码规则。
sep
这是分隔符参数,缺省列与列之间用逗号分隔。不过有很多单位由于历史数据采用的分隔符多种多样,为了适应这种情况,你可以用这个参数指定分隔符。
df.to_csv("a.csv", sep='\t')
五、Pandas绘图 matplotlib.pyplot出图
5.1 柱状图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
list1 = [
[99, 98, 97, 95, 89],
[89, 98, 76, 90, 88],
[76, 90, 98, 89, 89],
[99, 98, 97, 95, 89],
[96, 88, 93, 92, 99],
[94, 92, 98, 93, 81],
[92, 91, 91, 98, 81]
]
array1 = np.array(list1)
df = pd.DataFrame(array1, index=['第1次测试','第2次测试','第3次测试','第4次测试','第5次测试','第6次测试','第7次测试'], columns=['第一组','第二组','第三组','第四组','第五组'])
# 或使用df.plot(kind="bar")
df.plot.bar()
# plt.bar(['第1次测试','第2次测试','第3次测试','第4次测试','第5次测试','第6次测试','第7次测试'], [11,22,33,44,55,66,77])
plt.xticks()
plt.show()
- rotation 旋转
- mpl.rcParams["font.family"] = "FangSong" # 设置字体
- mpl.rcParams["axes.unicode_minus"] = False # 正常显示负号
- 横向的
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams["font.family"] = "FangSong" # 设置字体
mpl.rcParams["axes.unicode_minus"] = False # 正常显示负号
print(np.random.rand(10,4), type(np.random.rand(10,4)))
list1 = [
[99, 98, 97, 95, 89],
[89, 98, 76, 90, 88],
[76, 90, 98, 89, 89],
[99, 98, 97, 95, 89],
[96, 88, 93, 92, 99],
[94, 92, 98, 93, 81],
[92, 91, 91, 98, 81]
]
array1 = np.array(list1)
df2 = pd.DataFrame(array1, index=['第1次测试','第2次测试','第3次测试','第4次测试','第5次测试','第6次测试','第7次测试'],columns=['第一组','第二组','第三组','第四组','第五组'])
print(df2)
df2.plot.barh(stacked=True)
plt.xticks(rotation=360)
plt.show()
5.2 散点图(机器学习的聚类)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
# 创建一个DataFrame
data = {'x': [1, 2, 3, 4, 5], 'y': [2, 4, 6, 8, 10]}
df = pd.DataFrame(data)
# 绘制散点图
df.plot(kind='scatter', x='x', y='y')
# 显示图形
plt.show()
5.3 饼状图
import matplotlib as mpl
mpl.rcParams["font.family"] = "FangSong" # 设置字体
mpl.rcParams["axes.unicode_minus"] = False # 正常显示负号
data1 = pd.Series({'中专': 0.2515, '大专': 0.3724, '本科': 0.3336, '硕士': 0.0368, '其他': 0.0057})
# 将序列的名称设置为空字符,否则绘制的饼图左边会出现None这样的字眼
data1.name = ''
# 控制饼图为正圆
plt.axes(aspect='equal')
# plot方法对序列进行绘图
data1.plot(kind='pie', # 选择图形类型
autopct='%.1f%%', # 饼图中添加数值标签
radius=1, # 设置饼图的半径
startangle=180, # 设置饼图的初始角度
counterclock=False, # 将饼图的顺序设置为顺时针方向
title='失信用户的受教育水平分布', # 为饼图添加标题
wedgeprops={'linewidth': 1.5, 'edgecolor': 'green'}, # 设置饼图内外边界的属性值
textprops={'fontsize': 10, 'color': 'black'} # 设置文本标签的属性值
)
# 显示图形
plt.show()