python pandas库㈠
前言
一、pandas概述
pip install pandas
二、Series对象
①Series对象特点
pandas中主要有两种数据结构,分别是:Series和DataFrame。
Series与Python的基本数据结构list也很相近, 它们的区别是:list中的元素可以是不同的数据类型,而Series中的元素只能是相同的数据类型,这样可以更有效的使用内存,提高运算效率。
②Series对象的创建
import pandas as pd
s = pd.Series(data,index,dtype,copy)
(1)从列表(list)创建Series对象
我国的四大发明是:造纸术、指南针、火药和印刷术。通过 list创建一个Series对象来存储它们,代码如下所示。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'])
inventions
#第2行代码通过调用pandas的Series构造方法创 建对象,初始化参数为代表四大发明的list。
#执行第3行代码,inventions的输出结果如图。创建Series对象时会自动生成整数标签,默认值从0开始至数据长度减1,如上述示例的0,1,2,3。dtype是数据类型,这里存储的元素为字符串,输出为object类型。
在Series构造方法中,还可以通过index参数来指定标签值,代码如下所示
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'],index=['a','b','c','d'])
#通过index参数来指定标签值后,输出标签分别为a, b, c, d。
inventions
(2)从字典(dict)创建Series对象
我国的四大名著是:《水浒传》、《三国演义》、《西游记》、《红楼梦》。通过字典(键为作者名,值为书名)创建一个Series对象来存储它们,代码如下所示。
import pandas as pd
books= pd.Series({'施耐庵':'水浒传','罗贯中':'三国演义','吴承恩':'西游记','曹雪芹':'红楼梦'})
books
#第2行代码通过调用pandas的Series构造方法创建对象,初始化参数为存储了四大名著的作者名和书名的字典。
#执行第3行代码,books输出结果如图2所示,输出标签为字典的键(作者名),数据为字典的值(书名)。
(3)Series对象的常用属性和方法:
import pandas as pd
books= pd.Series({'施耐庵':'水浒传','罗贯中':'三国演义','吴承恩':'西游记','曹雪芹':'红楼梦'})
books.index
books.values
books.dtype
books.empty
books.size
books.head()
books.tail()
③Series对象的索引
Series对象可以使用标签,下标和切片三种方式进行索引。
(1)标签索引
使用标签索引:用[ ]表示,[ ]里面是标签的名称,输出结果 为该标签对应的元素。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'],index=['a','b','c','d'])
inventions['a']
#第2行代码通过index指定标签依次为 'a','b','c','d'。
#执行第3行代码,通过标签'a'索引输出 第一个元素‘造纸术’。
(2)下标索引
使用下标索引:下标索引是从0开始,[0]是Series的第一个元 素,[1] 是Series的第二个元素,以此类推。如果Series对象中 有N个元素,则下标的取值为0至N-1。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术']) inventions[0]
#下标0表示第一个元素
注意:由于Series对象本身默认的标签是整数,从0 开始至数据长度减1。那么当使用[-1]想要选取最后一个元素时, pandas会把传入的整数认为是对其本身标签的引用,由于其本身标签不存在-1,因此就会抛出KeyError:-1错误。但是,当其本身的标签不是整数类型,而是其他类型时,则[-1]索引输出最后一个元素, 当下标为负数时则反向输出,以此类推。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'],index=['a','b','c','d'])
inventions[-1] #'印刷术'
inventions[-2] #'火药'
(3)切片索引
使用切片索引:既可以使用标签,又可以使用下标进行切片索引。
(1)Series使用标签进行切片索引时,既包含了标签索引开始的元素,也包含了标签索引结束的元素。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'],index=['a','b','c','d'])
inventions['a':'c']
#执行第3行代码,使用标签进行切片['a':'c']索引时,则会输出前三个 元素。
Series使用下标进行切片索引时,不会包含下标索引结束的元素。
import pandas as pd
inventions = pd.Series(['造纸术','指南针','火药','印刷术'],index=['a','b','c','d'])
inventions[0:2]
#执行第3行代码,使用标签进行切片[0:2]索引时,则只会输出前两个元素。
④Series对象的操作
Series还提供了很多方法可以对Series对象中的元素进行增 加、删除、修改、排序和筛选等操作。
我国的五大名山是:东岳泰山(海拔约1545米)、南岳衡山(海拔约 1300.2米)、西岳华山(海拔约2154.9米)、北岳恒山(海拔约2016.1 米)、中岳嵩山(海拔约1491.7米)。创建一个 Series对象存储 五大名山的数据?
import pandas as pd
mountains = pd.Series({'东岳泰山':1545,'南岳衡山 ':1300.2, '西岳华山':2154.9})
mountains
#山名作为元素的标签,山的海拔高度作为元素的值,其类型为float。
(1)增加
1、Series对象可以通过标签来增加单个值。
import pandas as pd
mountains = pd.Series({'东岳泰山':1545,'南岳衡山 ':1300.2, '西岳华山':2154.9})
mountains
mountains['北岳恒山'] = 2016.1
mountains
#mountains的末尾增加了 北岳恒山和它的海拔高 度。
2、Series还可以通过append()方法来连接另一个Series对象,并将其附加到前一个Series对象的末尾。
mountain2 = pd.Series({'中岳嵩山':1491.7}) mountains.append(mountain2) # 通过append连接另一个Series对象
#mountains的末尾增加了中岳嵩山和它的海拔高度
(2)删除
Series提供了drop()方法,可以通过标签实现删除相应的元素值。
import pandas as pd
mountains = pd.Series({'东岳泰山':1545,'南岳衡山':1300.2,'西岳华山':2154.9})
mountains.drop('南岳衡山',inplace=True) #删除南岳衡山,直接在原数据操作
mountains
还可以通过标签数组,使用drop()方法一次性删除多个值,代码如下所示。
import pandas as pd
mountains = pd.Series({'东岳泰山':1545,'南岳衡山':1300.2,'西岳华山':2154.9})
mountains.drop(labels=['东岳泰山','西岳华山'],inplace=True) #删除东岳泰山,西岳华山
mountains
#mountains使用drop()方法通过 labels参数指定的标签数组删除了 东岳泰山和西岳华山以及它们的 海拔高度。
(3)修改
Series可以直接通过标签来修改元素的值。
import pandas as pd
mountains = pd.Series({'东岳泰山':1545,'南岳衡山':1300.2,'西岳华山':2154.9})
mountains['西岳华山']=2155 #修改西岳华山的海拔高度为2155
mountains
(4)排序
①按值排序:sort_values()
- Series可以使用sort_values()方法按存储的元素的值来排序,排 序时默认升序。
- 设置参数ascending=False,可以指定按降序排列。
import pandas as pd
mountains = pd.Series({'东岳泰山':1545, '南岳衡山':1300, '西岳华山':2155, '北岳恒山':2016,' 中岳嵩山':1492})
mountains.sort_values() #按值排序,默认升序
mountains.sort_values(ascending=False) #按值排序,指定降序
②按标签排序:sort_index()
- Series可以使用sort_index()方法按标签来排序,默认升序
- 设置参数ascending=False,可以指定按降序排列
- 当标签为字符时,采用Unicode编码值来排序
import pandas as pd
mountains = pd.Series({'东':1545,'南':1300,'西':2155,'北':2016,'中':1492})
mountains.sort_index() # 按标签(Unicode编码)排序,默认升序
mountains.sort_index(ascending=False) # 按标签(Unicode编码)排序,指定降序
#标签为东(Unicode编码值\u4e1c),南(Unicode编码值\u5357),西 (Unicode编码值\u897f),北(Unicode编码值\u5317),中(Unicode编码值 \u4e2d)
(5)筛选
空值筛选:Series还提供了isnull()方法来判断是否元素有空值, 如果元素的值为空则输出False,否则输出True。
import pandas as pd
s = pd.Series({'a':1,'b':2},index=['a','b','c'])
s.isnull() #判断s中的元素是否存在空值
s[s.isnull()] #查看s中的元素的空值
⑤案例实现
已知小明同学的Python、Java、C、C++、JavaScript和C#六 门课程的成绩,如表2.3.6所示
①访问表2.3.4中的常用属性和方法,输出程序运行结果。
#①
# 创建一个xiaoming的Series对象
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
#(1)增加
xiaoming['Java'] = 100
xiaoming2 = pd.Series({'PHP':96})
xiaoming.append(xiaoming2)
# 删除
xiaomings = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaomings.drop('C++',inplace = True)
xiaoming12 = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming12.drop(labels = ['C#','C++'],inplace = True)
# 修改
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming['C'] = 100
# 排序
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
# xiaoming.sort_values() 默认升序
xiaoming.sort_values(ascending = False)
# 筛选
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming.isnull()
②通过标签索引,分别查看科目Python和Java的成绩
# (2)
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
print(xiaoming['Python'])
print(xiaoming['Java'])
③通过标签,删除C#的成绩。
# (3)
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming.drop('C#',inplace = True)
xiaoming
④通过标签,修改C++的成绩为72
#(4)
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming['C++'] = 72
xiaoming
⑤将成绩按照降序排列,并输出排序后的结果。
# (5)
xiaoming = pd.Series({'Python':90,'Java':88,'C':75,'C++':70,'Javascript':85,'C#':86})
xiaoming.sort_values(ascending=False)
三、DataFraame对象
①DataFraame对象特点
- DataFrame是一种二维表格型的数据结构,包含有一组有序的列,每一列的值可以是不同的类型(数值、字符串、布尔型等)。
- DataFrame既有行标签(index标签),也有列标签(column标签),DataFrame的每一列就是一个Series对象,可以被看作是由Series组成的字典。
②DataFraame对象的创建
DataFrame对象的创建主要使用pandas的DataFrame构造方法
import pandas as pd
df=pd. DataFrame( data, index, columns, dtype, copy)
(1)通过二维数组创建DataFrame对象
import pandas as pd
data=[['黄山','安徽','黄山',1864.8],['泰山','山东','泰安',1524], ['庐山','江西','九江',1474],['恒山','山西','大同',2016], ['华山','陕西','渭南',2154.9],['衡山','湖南','衡阳',1300.2]]
columns=['mountain', 'province', 'city', 'height']
mountainsDF=pd. DataFrame( data=data, columns=columns)
mountainsDF
(2)通过字典创建DataFrame对象
import pandas as pd
mountainsDF= pd.DataFrame({'mountain':['黄山','泰山','庐山','恒山','华山','衡山'],
'province':['安徽','山东','江西','山西','陕西','湖南'],
'city':['黄山','泰安','九江','大同','渭南','衡阳'],
'height':[1864.8,1524,1474,2016,2154.9,1300.2]})
mountainsDF
(3)DataFrame对象的常用属性和方法
import pandas as pd
mountainsDF= pd.DataFrame({'mountain':['黄山','泰山','庐山','恒山','华山','衡山'],
'province':['安徽','山东','江西','山西','陕西','湖南'],
'city':['黄山','泰安','九江','大同','渭南','衡阳'],
'height':[1864.8,1524,1474,2016,2154.9,1300.2]})
index = ['a','b','c','d','e','f']
mountainsDF.index = index
mountainsDF['a':'c']
mountainsDF.T
mountainsDF.shape
mountainsDF.shape[0]
mountainsDF.info()
mountainsDF.head()
mountainsDF.dtypes
③DataFrame对象的索引
DatarFame对象包含列标签和行标签,可以直接通过操作它们实现列索引和 行索引,也可以利用DataFrame提供的loc和iloc操作(花式索引)实现索引。
(1)列索引
DataFrame对象的列索引:直接通过列标签就可以实现索引。
import pandas as pd
mountainsDF= pd.DataFrame({'mountain':['黄山','泰山','庐山','恒山','华山','衡山'], 'province':['安徽','山东','江西','山西','陕西','湖南'], 'city':['黄山','泰安','九江','大同','渭南','衡阳'], 'height':[1864.8,1524,1474,2016,2154.9,1300.2]})
mountainsDF[['mountain']] # 获取'mountain'列数据
mountainsDF[['mountain', 'city']] # 获取'mountain'和'city'列数据
(2)行索引
DataFrame对象的行索引:直接通过行标签就可以实现索引。
如果指定了DataFrame的行标签(index),可以通过行标签切片的方式 获取行数据,而且包含了结束标签表示的行数据。
index=[‘a’,‘b’,‘c’,‘d’,‘e’,‘f’]
mountainsDF.index = index # 设置行标签
mountainsDF[‘a’:‘c’] # 获取前3行数据
DataFrame对象的行索引: 还可以通过下标切片实现索引。
mountainsDF[0:1] #通过行标签(整数下标)切片方式获取第1行数据
mountainsDF[1:3] #通过行标签(整数下标)切片方式获取第2-3行数据
(3)loc和iloc花式索引
DataFrame的loc和iloc花式索引: 只获取一部分行和一部分列的数据
(1)loc基于标签索引(标签名称,如’a’, 'b’等),通过标签获取相应的数据,且包含结束标签包含的数据。当执行下标切片索引时,既包含起始标签表示的数据,也包含结束标签表示的数据。
(2)iloc基于下标索引(整数值,从0开始至长度-1),通过下标获取相应的数据,且不包含结束下标包含的数据。当执行下标切片索引时,只包含起始下标表示的数据,不包含结束下标表示的数据。
mountainsDF.loc[3:4,['mountain', 'height']] # 基于标签完成花式索引
mountainsDF.iloc[3:5,[0,3]] # 基于下标完成花式索引
④DataFrame对象的操作
DataFrame是一种二维数据表结构,也能够对行和列数据实现增加、 删除、修改、排序和筛选的操作。
(1)增加
增加:添加一行或者一列
- 添加行有df.loc[ ]以及df.append()这两种方法
- 添加列有df[ ]和df.insert()两种方法
- [ ]里面为行标签或者列标签
①添加行:df.loc[ ]
#添加一行
mountainsDF.loc[6] =['嵩山','河南','登封',1492]
mountainsDF
#使用df.loc[ ]方法完成在mountainsDF 最后增加一行数据
②添加行:df.append()
#添加一行
df2=pd.DataFrame({'mountain':[ '嵩山','武夷山'],'province':['河南','福建'], 'city':['登封','南平'],'height':[1492, 2158]})
#合并,可以重新排列行标签
mountainsDF2 = mountainsDF.append(df2, ignore_index=True)
mountainsDF2
①添加列:df[ ]
#添加一列:df[]
mountainsDF['level']=['5A', '5A', '5A', '5A', '5A', '5A']
mountainsDF
②添加列:df.insert()方法
#添加一列:df.insert()方法
mountainsDF.insert(1,'level',['5A','5A','5A','5A','5A','5A'])
mountainsDF
(2)删除
删除:DataFrame提供了drop()方法删除一行或一列。
DataFrame.drop(labels,axis, index, columns, inplace=False)
①删除行
mountainsDF. drop([0, 1]) #删除mountainsDF前2行数据
mountainsDF. drop(index=[0, 1]) #删除mountainsDF前2行数据
②删除列:指定axis=1
#删除'province','city'2列数据
mountainsDF.drop(['province','city'],axis=1)
mountainsDF.drop(columns=['province','city'],axis=1)
(3)修改
修改:包括数据的修改和行/列标签的修改
(1)数据的修改
- 修改DataFrame中的数据,原理是将这部分数据提取出来,重新赋值 为新的数据。需要注意的是,数据更改直接针对DataFrame原数据更 改,操作无法撤销,如果做出更改,需要对原数据进行备份。
- iloc[ ]方法的使用和loc方法类似, 主要是先基于下标定位再修改数据。
- 数据的修改常使用loc[ ]方法,先定位某个位置的数据,然后对此位置 的数据进行修改。使用此方法可以对DataFrame进行的修改分为3种情 况,具体如下:
• ①对1行、多行数据进行修改
• ②对1列、多列数据进行修改
• ③对某区域的数据进行修改
①对1行、多行数据进行修改
#一行
mountainsDF.loc[1:1,['mountain','province','city','height']] = ['武夷山','福建','南平',2158] #修改第2行数据
mountainsDF
#第1行代码的1:1表示选取第2行数据,然后 对指定的4个标签('mountain', 'province', 'city','height')的相应数据进行修改,等号 右边为新的赋值。
#多行
mountainsDF.loc[0:1,['mountain','province','city','height']]= [[ '嵩山','河南','登封',1492], ['武夷山','福建','南平',2158]]
#修改mountainsDF第1-2行数据
#0:1 表示定位前两行
mountainsDF
②对1列、多列数据进行修改
#一列
mountainsDF.loc[:,['province']]= ['安徽省','山东省','江西省','山西省','陕西省','湖南省']
#第1行代码的:表示所有行,
#然后 对指定的['province']列进行修改,
# 等号右边为新的赋值。
mountainsDF
#多列
mountainsDF.loc[:,['province', 'city']]= [['安徽省','黄山市'],['山东省','泰安市'], ['江西省','九江市'],['山西省','大同市'], ['陕西省','渭南市'],['湖南省','衡阳市']]
mountainsDF
#第2行代码的:表示所有行,然后对指定的['province', 'city']2列进行修改,等号右边为新的赋值。
③对某个区域的数据进行修改
#对前2行的province列和 city列进行修改
mountainsDF.loc[0:1,['province', 'city']]=[['安徽省','黄山市'],['山东省','泰安市']]
mountainsDF
(2)标签的修改:rename ()方法修改行标签和列标签的名称
①行标签的修改
mountainsDF.rename(index={0:'a',1:'b'},inplace=True) #修改前2行的标签名称
mountainsDF
#第1行代码mountainsDF调用 rename()方法,指定index 参数为字典形式完成行标签 修改,inplace=True表示直接修改原数据。
②列标签的修改
mountainsDF.rename(columns={'province':'p','city':'c'},inplace=True)
#修改mountainsDF的province列和city列标签名
mountainsDF
#第1行代码mountainsDF调用rename()方法,指定columns参数为字典形式完成列标签修改,inplace=True表示直接修改原数据。
(4)排序
排序:可以按值排序,也可以按行/列标签排序。按值排序使用 sort_values()方法,按标签排序使用sort_index()方法。
(1)按值排序:sort_values() 通常按列的值排,默认升序
#按height列的值降序排列
mountainsDF.sort_values(by='height',axis=0,ascending=False,inplace=True)
mountainsDF
(2)按标签排序:sort_index() 默认axis=0按行标签,升序
#按行标签降序排列
mountainsDF.sort_index(axis=0,ascending=False,inplace=True)
mountainsDF
(3)按标签排序:sort_index() axis=1按列标签
#按列标签升序排列
mountainsDF.sort_index(axis=1,inplace=True)
mountainsDF
(5)筛选
(1)条件筛选
#按height列的值进行条件筛选
mountainsDF[mountainsDF['height']>1500]
#筛选输出海拔高度大于1500米的山的信息
(2)空值筛选: isnull() 方法 None也表示空值
import pandas as pd
mountainsDF= pd.DataFrame({'mountain':['黄山','泰山','庐山','恒山','华山','衡山'], 'province':['安徽','山东','江西',None,'陕西','湖南'], 'city':['黄山',None,'九江','大同','渭南','衡阳'], 'height':[1864.8,1524,1474,2016,2154.9,1300.2]})
mountainsDF.isnull().any() #查看每一列是否存在空值
mountainsDF[mountainsDF.isnull().T.any()] #筛选出包含空值的行
⑤案例实现
利用DataFrame对象,完成以下任务。
①找出成绩表中的空值,并重新设定值(可自行设定)。 ②小李同学和小杨同学对换宿舍,删除小李同学的成绩,并添加 小杨同学的成绩(Python:86, Java:88),按照行标签升序重 新排列数据。
③在Java语言之前再添加他们的C语言成绩(小明:75,小王: 89,小杨:82,小赵:85)
④按照他们的Python成绩从高到低排序。
import pandas as pd
scores = pd.DataFrame({'name':['小明','小王','小李','小赵'], 'Python':[90,95,65,None],'Java':[92,None,68,80]})
#(1)
scores.isnull().any()
scores[scores.isnull().T.any()]
scores.loc[1:1,['Java']] = 98
scores.loc[3:3,['Java']] = 85
scores
#(2)
scores.drop([2],inplace=True)
scores
scores.loc[2] = ['小杨',86,88]
scores.sort_index(ascending=True,inplace=True)
scores
#(3)
scores.insert(2,'C',[75,89,82,85],allow_duplicates=False)
scores
#(4)
scores.sort_values(by='Python',axis=0,ascending=False,inplace=True)
scores