200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > AI算法工程师 | 03人工智能基础-Python科学计算和可视化(三)Pandas

AI算法工程师 | 03人工智能基础-Python科学计算和可视化(三)Pandas

时间:2022-12-29 05:54:15

相关推荐

AI算法工程师 | 03人工智能基础-Python科学计算和可视化(三)Pandas

文章目录

Python 之 数据处理分析模块 Pandas一、Pandas 开发环境搭建二、Pandas 数据类型1. Series 对象创建2. DataFrame 对象创建3. 获取 Series 对象的值4. 获取 DataFrame 的值5. Series 的方法6. Series 的条件过滤7. DataFrame 的条件过滤三、处理缺失值1. 缺失值查看2. 缺失值删除3. 缺失值填充四、拼接五、merge 的使用

Python 之 数据处理分析模块 Pandas

Pandas 是基于 Numpy 的一套数据分析工具,该工具是为了解决数据分析任务而创建的。

数据模型繁多:Pandas 纳入了大量标准的数据模型,提供了高效地操作大型数据集所需的工具;导入数据方便:Pandas 可以从各种文件格式中导入数据,如:CSV、JSON、SQL、Excel 等;处理数据便捷:Pandas 是 Python 语言的一个扩展程序库,提供了许多快速便捷地处理数据的函数和方法。

小贴士

本文中多处使用到 Numpy 模块,若对其不熟悉,可先浏览:AI算法工程师 | 03人工智能基础-Python科学计算和可视化(一)Numpy

一、Pandas 开发环境搭建

说明

Pandas 是第三方程序库,在使用 Pandas 前需确保安装了 Pandas 库。如果使用的是 Anaconda Python 开发环境,那么 Pandas 已经被集成进 Anaconda,并不需要单独安装。(由于自己使用的是 Miniconda Python 开发环境,需要单独安装 Pandas )

测试与安装

若不清楚 Python 环境是否安装了 Pandas,可先测试

Windows电脑中按键win + R后输入“cmd” → 在 cmd 的命令窗口输入python→进入 python 环境中后,输入import pandas并回车 →若输入后提示模块没有找到“ModuleNotFoundError: No module named 'pandas'”,说明未安装 Pandas;若什么都没显示,则说明已安装。注:输入exit()可退出 python 环境。

cmd 中使用 pip 命令安装Pandas:(注意该命令是在 cmd 中,而非 python 环境中)

# 安装命令1(不指定版本)pip install pandas# 安装命令2(指定下载源,这样下载得更快)pip install pandas -i https://pypi.tuna./simple

安装完成后,可以测试一下 Pandas 是否安装成功。下面是导入 pandas 模块的语句(该语句是在 python 环境中输入),若不报错,说明 Pandas 已经安装成功了。

# 导入 pandas 模块,并起别名为 pd # 注意:每次使用 pandas 前均需写导入模块的语句import pandas as pd # 扩:这是查看 pandas 库的版本号的命令import pandaspandas.__version__ # 查看版本号(命令中,version前后均分别有两个下划线)

图示

二、Pandas 数据类型

Pandas 中两个重要的数据类型:SeriesDataFrame

Series:表示数据列表(一维)DataFrame:表示二维数据集(二维)

1. Series 对象创建

Series 语法格式

pandas.Series( data, index, dtype, name, copy)'''参数说明:· data :一组数据(ndarray 类型)· index:数据索引标签(若不指定,默认从 0 开始)· dtype:数据类型,默认会自己判断· name :设置名称(默认为 False)'''

示例1 - 使用列表创建

使用列表创建 Series 对象

import pandas as pd # 导包data = pd.Series([1,2,3,4,5]) # 返回一个序列data

Series 对象本质上是调用 numpy 创建了一个一维数组,之后在其身上赋予了一个索引,从而组成了一个 Series。即:Series 对象中有 ① numpy 数组、② index 索引。

因此,pandas 中有两个重要的属性values(Series 对象的原始数据) 和index(对应 Series 对象的索引对象)

Series 对象中两个重要的属性 values 和 index

data.values # 查看属性 valuesdata.index # 查看属性 index

若不想让索引从 0 开始,可以指定索引值(index 属性)

data = pd.Series([4,3,6,7,9],index=['one','two','three','four','five'])data

也可使用 list 列表指定 index 属性

data = pd.Series([4,3,6,7,9],index=list('abcde'))data

示例2 - 使用字典创建

使用字典创建 Series 对象

import pandas as pd # 导包# 使用字典创建 Series 对象,默认将 key 作为 index 属性population_dict={'bj':3000,'gz':1500,'sh':2800,'sz':1200} # 可传字典population_series=pd.Series(population_dict)population_series

用字典创建 Series 对象,可指定 index 属性值。若 key 不存在,则值为 NaN(代表空值)

# 如果存在取交集sub_series=pd.Series(population_dict,index=['bj','sh']) sub_series

# 如果不存在则值为 NaNsub_series=pd.Series(population_dict,index=['bj','xa'])sub_series

示例3 - 使用标量与 index 创建

标量与 index 属性创建 Series 对象

import pandas as pd # 导包data = pd.Series(6,index=[6,5,8,9,3])data

2. DataFrame 对象创建

关于 DataFrame

DataFrame 可以看成一个数据框(表格),有行与列。其中,每一列可以是不同的值类型,如:数值、布尔、字符串等。

图示 - 由 Series 组成的 DataFrame:

DataFrame 语法格式:

pandas.DataFrame( data, index, columns, dtype, copy)'''参数说明:· data :一组数据(ndarray、series, map, lists, dict 等类型)· index :数据索引标签(相当于:行索引)· columns:列索引(默认为 RangeIndex 0, 1, 2, …, n)· dtype :数据类型· copy :拷贝数据(默认为 False)'''

示例1 - 使用 Series 及字典创建

将两个 Series 对象作为字典的值,就可以创建一个 DataFrame 对象

import pandas as pd # 导包# 字典population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}area_dict={'beijing':300,'guangzhou':200,'shanghai':180}# 创建 2 个 seriespopulation_series=pd.Series(population_dict)area_series=pd.Series(area_dict)# 通过 DataFrame 创建数据框citys=pd.DataFrame({'area':area_series,'population':population_series})citys

查看 DataFrame 对象的 values、index 和 columns 属性

citys.index # 数据索引标签(相当于:行索引)citys.values # 数据值citys.columns # 列索引

示例2 - 使用列表创建

既然可以用列表创建 Series 对象,那是不是也可以使用列表创建 DataFrame 对象呢?

import pandas as pd # 导包# 字典population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}area_dict={'beijing':300,'guangzhou':200,'shanghai':180}# 使用列表创建 DataFrame 对象citys=pd.DataFrame([population_dict,area_dict]) # 直接把两个字典放在列表中citys # 会将‘beijing’‘shanghai’ ‘guangzhou’作为表头(列索引)

从结果中可以看到,使用列表创建的 DataFrame 对象,若未指定 index,则行索引默认从 0 开始。

使用列表创建 DataFrame 对象,可通过指定 index 设置行索引

import pandas as pd # 导包# 字典population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}area_dict={'beijing':300,'guangzhou':200,'shanghai':180}# 创建 DataFrame 对象,并设置行索引citys=pd.DataFrame([population_dict,area_dict], index=['population','area']) # 指定索引号名称citys

对于上方的代码而言,可通过指定 columns,实现取某列(或过滤)的效果

pd.DataFrame([population_dict,area_dict], index=['population','area'],columns=['beijing','guangzhou']) # 指定 columns,设置列索引

创建 DataFrame 对象,并通过指定 columns 设置列索引

import pandas as pd # 导包# 创建 1 个 seriespopulation_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}population_series=pd.Series(population_dict)# 设置列索引pd.DataFrame(population_series,columns=['population']) # 指定列名# pd.DataFrame({'population':population_series}) # 与上一行的代码等价

使用列表创建 Dataframe 对象

import pandas as pd # 导包pd.DataFrame([{'a':i,'b':i*2} for i in range(3)])# pd.DataFrame([{'a':i,'b':i*2} for i in range(3)], index=['一','二','三']) # 指定行名称

示例3 - 使用二维数组创建

使用一个二维数组并指定 columns 和 index 创建 DataFrame 对象

import pandas as pd # 导包import numpy as np# 指明行名称、列名称pd.DataFrame(np.random.randint(0, 100, (4,3)), index=['a','b','c','d'], columns=['a','b','c'])

示例4 - 使用字典创建

创建一个数据集

import pandas as pd # 导包pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]})data # 字典中所有的键都作为表头(列索引)

指定列索引

import pandas as pd # 导包data = pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]},columns=['Sno','Sex','Age','Score'])data

指定行索引与列索引

import pandas as pd # 导包data = pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])data

小贴士:

关于 DataFrame 的详细介绍,可参考: 菜鸟教程——Pandas 数据结构 - DataFrame

3. 获取 Series 对象的值

示例

Series 对象的切片与索引

import pandas as pd # 导包data = pd.Series([45,6,2,3,5],index=list('abcde'))display('根据key获取:',data['a'])display('切片获取:',data['a':'d']) # 注意,这里(标签索引)不是左闭右开,会取到 ddisplay('索引获取:',data[1]) # 取第二个display('索引切片:',data[2:4])# 这里(位置索引)取值时,是左闭右开

可以看到,Series 和 ndarray 数组类似,可以通过索引来访问元素。但 Series 对象的索引可分为位置索引和标签索引。

其中,标签索引进行切片时:左闭右闭;而位置索引:左闭右开。

当 Series 对象的标签索引和位置索引存在相同时,无法区分是按哪种索引获取,怎么办?

data=pd.Series([5,6,7,8],index=[1,2,3,4])data[1]

上方的 Series 对象 data 中,位置索引与标签索引有相同值 1,则 data[1] 代表的含义便不明确,此时需使用loc(标签索引)、iloc(位置索引)。

使用 Series 对象中 loc 与 iloc 获取值

data.loc[1] # 根据名字(标签索引)取值data.iloc[1] # 根据位置索引取值

4. 获取 DataFrame 的值

获取 DataFrame 的值的介绍

DataFrame 对象获取的数据:

可传入具体的列名 —— 通过列名选择数据的方式叫做普通索引;还可以传入具体列的位置( iloc 方法)—— 传入列的位置选择数据的方式叫做位置索引

其中,获取连续的某几列时,用普通索引和位置索引都可以做到。由于要获取的列是连续的,所以需要对列进行切片来获取数据。

获取的方式主要有两种:

一种是普通索引,即传入具体行索引的名称,需要用到 loc 方法;另外一种是位置索引,即传入具体的行数,需要用到 iloc 方法。

示例1 - 获取列

创建 DataFrame 对象

import pandas as pd # 导包import numpy as npdata=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('ABCD'))data

获取列:① 传入具体的列名

print('获取‘B’列:')print(data['B']) # 如果要获取一列,则只需要传入一个列名print('获取‘A’‘C’两列:')print(data[['A','C']]) # 如果是同时选择多列,则传入多个列名(用一个 list 存放)即可

获取列:② 传入具体列的位置

print('获取第 1 列:')print(data.iloc[:,0])print('获取第 1 列和第 3 列:')print(data.iloc[:,[0,2]])# 说明:iloc 后的方括号中# ① 逗号之前的部分表示要获取的行的位置。只输入一个冒号,不输入任何数值表示获取所有的行;# ② 逗号之后的方括号表示要获取的列的位置,列的位置同样也是从 0 开始计数。

获取连续的几列(切片获取)

print('获取 A B 两列,使用位置索引获取:')print(data.iloc[:,0:2])print('获取 A B C 三列,使用普通索引获取:')print(data.loc[:,'A':'C'])

示例2 - 获取行

获取某一行或某几行

print('获取 a 行,普通索引获取:')print(data.loc['a'])print('获取 a c 行,普通索引获取:')print(data.loc[['a','c']])print('获取第 1 行,位置索引获取:')print(data.iloc[0])print('获取第 1 行第 3 行,位置索引获取:')print(data.iloc[[0,2]])

获取连续的几行(切片获取)

# 选择连续的某几行和选择连续某几列类似:把连续行的位置用一个区间表示print('选择第 1 行 第 2 行,使用位置索引:')print(data.iloc[0:2])print('选择 a 行 b 行,使用普通索引:')print(data.loc['a':'b'])

示例3 - 同时获取行和列

同时选择连续的部分行和部分列

print('同时获取 a b c 行,A B 列,使用普通索引:')print(data.loc['a':'c','A':'B'] )print('同时获取 a b 行,A B 列,使用位置索引:')print(data.iloc[0:2,0:2])

同时选择不连续的部分行和部分列

print('同时获取 a c 行,ABD 列,使用普通索引:')print(data.loc[['a','c'],['A','B','D']])print('同时获取 a c 行,ABD 列,使用位置索引:')print(data.iloc[[0,2],[0,1,3]])

5. Series 的方法

Series 对象中有很多常用的方法可以对数据进行各种处理。例如:

示例 - 对数据集进行各种运算,并排序

创建一个数据集

import pandas as pd # 导包data = pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])display('数据集',data)

计算平均值、最大值、最小值、标准差

ages = data['Age'] # 获取数据集中 Age 列的所有print(ages)ages.mean(), ages.min(), ages.max(), ages.std()

排序(正序)

ages.sort_values() # 对 Age 列进行排序(默认正序排序)

降序排序

ages.sort_values(ascending=False) # 对 Age 列进行降序排序

6. Series 的条件过滤

Series 对象也可像 SQL 语句一样,通过指定条件进行数据的过滤。

示例

筛选出成绩大于平均值的数据

import pandas as pd # 导包# 创建数据集data = pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])# 取出 'Score' 列的数据,并对数据进行筛选scores = data['Score']print(scores.mean()) # 平均值scores[scores>scores.mean()] # 筛选出大于平均值的

7. DataFrame 的条件过滤

DataFrame 与 Series 类似,也可使用条件进行过滤。

示例

一个条件进行筛选:输出数据中所有成绩大于平均值的记录

import pandas as pd # 导包# 创建数据集data = pd.DataFrame({'Name':['zs','lisi','ww'],'Sno':['1001','1002','1003'],'Sex':['man','woman','man'],'Age':[17,18,19],'Score':[80,97,95]},columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])# 输出数据中所有成绩大于平均值的记录scores = data['Score'] # 取出 'Score' 列的数据print(scores.mean())data[scores>scores.mean()] # data 中取值

多个条件进行筛选

# 且ages = data['Age'] # 获取数据集中 Age 列的所有data[(scores>scores.mean()) & (ages<19)] # 成绩大于平均值,且 年龄小于 19

# 或data[(scores>scores.mean()) | (ages<19)] # 成绩大于平均值,或 年龄小于 19

根据条件进行筛选后,再通过 loc 取值

# 获取成绩大于平均值的所有记录,只显示 Sno Age Score 三列data[scores>scores.mean()].loc[:,['Sno','Age','Score']]

三、处理缺失值

何谓缺失值?缺失值是指由某些原因导致部分数据为空。

对于为空的这部分数据,一般有两种处理方式:

方式一:删除,即把含有缺失值的数据删除;方式二:填充,即把缺失的那部分数据用某个值代替。

1. 缺失值查看

在对缺失值进行处理前,需要把缺失值找出来,即查看哪列有缺失值。

Pandas 中缺失值用 NaN 表示,通过调用info()方法可看到返回的每一列的缺失情况。

示例

info() 方法查看缺失值

import pandas as pd # 导包import numpy as npdf=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])df.info() # 缺失值查看

isnull() 方法可判断哪个值是缺失值,若为缺失值则返回 True,否则返回 False

import pandas as pd # 导包import numpy as npdata=pd.Series([3,4,np.nan,1,5,None])print(data.isnull(),'\n') # isnull()方法判断是否是缺值print(data[data.isnull()],'\n') # 获取缺值print(data[data.notnull()]) # 获取非空值

2. 缺失值删除

缺失值分为两种:

一种是:一行中某个字段是缺失值;另一种是:一行中的字段全部为缺失值,即为一个空白行。

调用dropna()方法删除缺失值:

dropna() 方法默认删除含有缺失值的行,即只要某一行有缺失值就把这一行删除;如果想按列为单位删除缺失值,需要传入参数axis=’columns’

示例

dropna() 方法删除缺失值

import pandas as pd # 导包import numpy as npdf=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]]) # 3行 3列new_df = df.dropna() # 缺失值删除(默认为以行为单位剔除)new_df

按列进行删除缺失值(传入参数 axis=’columns’)

df.dropna(axis='columns') # 以列为单位剔除

若想删除空白行,需给 dropna() 方法中传入参数 how=’all’ ,默认值为 any

df.dropna(how='all') # 某行中所有数据为 nan 时才剔除该行

3. 缺失值填充

由于数据是宝贵的,一般情况下如果数据缺失比例不高,尽量不会选择删除,而是选择填充。

调用fillna()方法填充缺失值:

在 fillna() 方法中输入要填充的值,可对数据表中的所有缺失值进行填充;还可以通过 method 参数使用前一个数和后一个数来进行填充。

示例

Series 对象缺失值填充

import pandas as pd # 导包import numpy as npdata=pd.Series([3,4,np.nan,1,5,None])print('以 0 进行填充:')display(data.fillna(0))print('以前一个数进行填充:')display(data.fillna(method='ffill'))print('以后一个数进行填充:')display(data.fillna(method='bfill'))print('先按后一个,再按前一个')display(data.fillna(method='bfill').fillna(method='ffill'))

DataFrame 对象缺失值填充

import pandas as pd # 导包import numpy as npdf=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])print('使用数值 0 来填充:')display(df.fillna(0))print('使用行的前一个数来填充:')display(df.fillna(method='ffill'))print('使用列的后一个数来填充:')display(df.fillna(method='bfill' ,axis=1))

使用列的平均值进行填充(常用)

import pandas as pd # 导包import numpy as npdf=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])display(df) # 原数据 dffor i in df.columns:df[i]=df[i].fillna(np.nanmean(df[i])) # 将填充完后的序列赋值给原序列(达到修改原数据的效果)display(df) # 填充后的数据 df

四、拼接

示例1 - Series 对象拼接

使用 concat() 方法对 Series 对象进行拼接

import pandas as pd # 导包ser1=pd.Series([1,2,3],index=list('ABC'))ser2=pd.Series([4,5,6],index=list('DEF'))pd.concat([ser1,ser2])

示例2 - DataFrame 对象拼接

多个 df 对象拼接,默认找相同的列索引进行合并

import pandas as pd # 导包# 声明一个函数def make_df(cols,index):data={c:[str(c)+str(i) for i in index] for c in cols}return pd.DataFrame(data,index=index)# 调用函数,创建两个 DataFrame 对象df1=make_df('AB',[1,2])df2=make_df('AB',[3,4])# 拼接(默认找相同的列索引进行合并)pd.concat([df1, df2])

添加 axis 参数,可按列拼接

pd.concat([df1, df2], axis=1) # 按列拼接,axis=1与 axis='columns' 等价

从上图结果中可以看到,多个 df 对象按列拼接时,若行索引不同,行也会往下拼接,并用 NaN 填充没有的数据。

多个 df 对象拼接,当设置 axis=1 按列拼接时,相同的行索引会进行合并,如:

示例3 - DataFrame 对象拼接的索引重复问题

多个 df 对象拼接,索引(行索引)重复问题

import pandas as pd # 导包# 声明一个函数def make_df(cols,index):data={c:[str(c)+str(i) for i in index] for c in cols}return pd.DataFrame(data,index=index)# 调用函数,创建两个 DataFrame 对象df1=make_df('AB',[1,2])df2=make_df('AB',[1,2])# 拼接(默认找相同的列索引进行合并)pd.concat([df1, df2])

上方的行索引有重复,若想让结果的索引重新排放,可加 ignore_index 属性

# 解决索引重复问题,方式 1 :加 ignore_index 属性pd.concat([df1,df2], ignore_index=True)

还可通过加 keys 属性,解决索引重复问题

# 解决索引重复问题,方式 2 :加 keys 属性pd.concat([df1,df2],keys=['df1', 'df2'])

示例4 - join 拼接

两个 df 对象拼接,join 内连接做交集

import pandas as pd # 导包# 声明一个函数def make_df(cols,index):data={c:[str(c)+str(i) for i in index] for c in cols}return pd.DataFrame(data,index=index)# 调用函数,创建两个 DataFrame 对象a=make_df('ABC',[1,2])b=make_df('BCD',[3,4])# 内连接(取列相交部分)pd.concat([a,b],join='inner')

五、merge 的使用

pandas 中 的 merge 和 concat 类似,但主要是用于两组有 key column 的数据,统一索引的数据。通常也被用在 Database 的处理当中。

使用 merge 合并时有 4 种方式 how = [‘left’, ‘right’, ‘outer’, ‘inner’],默认为 inner。

示例 - merge 的使用

默认以 how=’inner’ 进行合并

import pandas as pd # 导包# 创建 DataFrame 对象left=pd.DataFrame({'key':['k0','k1','k2','k3'],'A':['A0','A1','A2','A3'],'B':['B0','B1','B2','B3'],}) # 通过字典方式传入3个列right=pd.DataFrame({'key':['k0','k1','k4','k3'],'C':['C0','C1','C2','C3'],'D':['D0','D1','D2','D3'],}) # 合并pd.merge(left, right) # 默认合并,此处以 'key' 作为公共部分(可能会丢数据)# 语句说明:# 先看left、right这两内容 是否有相同名字这一列,# 对相同列 key 的数据做交集,再把交集所对应的其他列数据合并到结果中去

参数 how=’outer’ 进行合并

pd.merge(left, right, how='outer') # 数据全部保留

参数 how=’left’ 进行合并

pd.merge(left, right, how='left') # 左侧的全部保留

参数 how=’right’ 进行合并

pd.merge(left, right, how='right')# 右侧的全部保留

—— 说明:本文写于 7.30~8.1,文中内容基于 python3,使用工具Jupyter Notebook编写的代码

(本文中使用函数前的 np 代表 Numpy 的别名,pd 为 Pandas 的别名,每次使用前需导入相关模块)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。