Day 078 Pandas

mac2025-08-14  11

Pandas

Pandas库基于Numpy库,提供很多用于数据操作与分析功能

pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。它是使Python成为强大而高效的数据分析环境的重要因素之一。

安装与使用

安装: pip install pandas | conda install pandas 使用: import pandas as pd

两个常用数据类型

pandas提供两个常用数据类型

SeriesDataFrame import pandas as pd import numpy as np

Series类型

Series类型类似numpy的一维数组,可将此类型看做一组数据与数据相关标签(索引)联合构成。

创建方式

列表等可迭代对象ndarray数组对象字典对象标量 # Series 带标签的一维数组 # 使用列表创建 # s = pd.Series([1,2,3]) # 使用可迭代对象 # s=pd.Series(range(5)) # ndarray数组对象 # s=pd.Series(np.array([1,2,3])) # 字典数据,Series对象的标签为字典数据中key # s=pd.Series({'a':1,'b':2,'c':3}) # 标量,使用index参数指定索引 s=pd.Series(33,index=['a','b','c']) display(s)

相关属性

index values shape size dtype

Series对象可以通过index与values访问索引与值

说明:

如果没有指定索引,则会自动生成从0开始后的整数值索引,也可以使用index显式指定索引 Series对象与index同样有name属性,Series的name属性可在创建时通过name参数指定。 当数值较多时,可以通过head和tail访问前后N个数据 Sereis对象的数组只能是一维数组类型 # s = pd.Series([1,2,3]) s = pd.Series([1,2,3],index=list('abc')) # 返回元素索引 display(s.index) # 返回元素的值 display(s.values,type(s.values)) # 返回元素的形状 display(s.shape) # 返回元素个数 display(s.size) # 返回元素数据类型 display(s.dtype) s = pd.Series([1,2,3],index=list('abc')) s.name='Sereis name' s.index.name='index name' display(s) ind = pd.Index(['a','b','c'],name='index name') s = pd.Series([1,2,3],index=ind,name='Series name') display(s) s = pd.Series(np.arange(1000)) # head查看前面数据,默认5条;tail查看后面的数据,默认是5条 # display(s.head(),s.tail()) display(s.head(3),s.tail(3)) # 只能传入一维数据 s = pd.Series(np.array([[1,2],[2,3]])) # 会报错 s

Series和ndarray索引访问比较

Series对象可以看做带标签的ndarray,其中标签和值类似字典的key和value,不支持负数

s = pd.Series([1,2,3]) # display(s) # display(s[0]) # Series类似于字典的key和value方式,不支持负数访问 # display(s[-1]) # 会报错 # ndarray类似于list索引,支持负数访问 x = np.array([1,2,3]) display(x[-1])

Series相关操作

Sereis在操作上与ndarray类似

支持广播与向量化运算支持索引与切片支持整数数组与布尔数组提取元素运算

Numpy统计函数也适用于Sereis类型,例如 np.mean,np.sum等。多个Sereis运算时,会根据索引进行对齐。当索引无法匹配时,结果值为NaN(缺失值) 说明

pandas或Sereis的isnull与notnull判断数据是否缺失Sereis对象可以使用运算符运算,也可以使用Sereis对象提供相关方法进行运算(指定缺失值的填充值)Sereis和Numpy对于空值(NaN)计算方式上不同。Numpy会处理NaN,而Sereis忽略NaN # Series和ndarray类似,也支持广播和向量化整体操作 s = pd.Series([1,2,3]) s2 = pd.Series([2,3,4]) # display(s*s2) display(s*2) s = pd.Series([1,2,3],index=[1,2,3]) s2 = pd.Series([2,3,4],index=[2,3,4]) # Series运算时候,根据标签进行匹配,如果是不一致,产生空值 # 空值和任何其他的值运算还是空值 np.nan/3=nan display(s*s2) np.nan/3 s = pd.Series([1,2,3],index=[1,2,3]) s2 = pd.Series([2,3,4],index=[2,3,4]) # 如果Series对象运算结果不想要空值,可以使用Sereis对象提供计算方法得到 s.add(s2,fill_value=10) s = pd.Series([1,2,3,float('NaN'),np.nan]) # 判断数据是否为空值 # display(s.isnull()) # 判断数据不是为空值 # display(s.notnull()) display(pd.notnull(s)) # 在统计函数中,numpy处理NaN,Sereis忽略Nan a = np.array([1,2,3,np.nan]) s = pd.Series([1,2,3,np.nan]) display(np.mean(a)) display(np.mean(s))

索引

标签索引与位置索引

当Sereis对象的index值为非数值类型,可以使用标签和位置索引,也可以显式指定标签或者位置索引访问

loc标签索引访问iloc位置索引访问

标签、位置数组索引与布尔数组索引

Sereis支持标签、位置数组索引与布尔数组索引,返回是原数据的拷贝

# s = pd.Series([1,2,3]) # display(s[0]) # 通过index指定标签信息,非数值类型标签信息 # Sereis对象既可以通过标签索引来访问,也可以通过位置索引来访问 s = pd.Series([1,2,3],index=list('abc')) display(s['a']) display(s[0]) # 通过index指定标签信息,数值类型标签信息 # 当指定索引是数值类型时候,位置索引失效 s = pd.Series([1,2,3],index=[2,3,4]) display(s[2]) # 错误 # display(s[0]) # Sereis对象提供iloc和loc来显式访问位置和标签索引 s = pd.Series([1,2,3],index=list('abc')) # loc专门来通过标签进行访问 display(s.loc['a']) # iloc专门来通过位置进行访问 display(s.iloc[0]) # 我们通过标签或位置数组来访问多个元素 s = pd.Series([1,2,3],index=list('abc')) display(s.loc['a']) display(s.loc[['a','c']]) display(s.iloc[[0,2]]) # 通过标签或位置数组来访问多个元素得到是原数据拷贝,彼此间不会互相干扰 s = pd.Series([1,2,3],index=list('abc')) s2 = s.loc[['a','c']] display(s,s2) s2['a']=100 display(s,s2) # 布尔数组索引访问Sereis中数据 s = pd.Series([1,2,3,4],index=list('abcd')) display(s>2) display(s[s>2])

切片

Series和ndarray数组一样支持切片访问多个元素,返回的数据和原数据共享内存

# Series对象和ndarray数组一样支持切片操作,且返回的数据和原数据共享内存 s = pd.Series([1,2,3,4]) s2 = s[0:3] display(s2) # 共享内存,修改其中一方会影响另外一方 s2[0] = 100 display(s2,s) # Sereis具有标签索引和位置索引,通过连着访问多个数据 s = pd.Series([1,2,3,4],index=list('abcd')) # 位置索引切片访问,不包含终止值 display(s.iloc[0:3]) # 标签索引切片访问,包含终止值 display(s.loc['a':'d'])

Series增删改查操作

s = pd.Series([1,2,3,4],index=list('abcd')) # 获取值,通过标签或者位置索引(或者2者数组) display(s.loc['a']) display(s.iloc[0]) # 修改值 s.loc['a']=100 # 增加值,类似字典操作 s['f']=5 display(s) # 删除值,类似字典操作 # del s['f'] # display(s) # 删除值,drop,inplace为false # inplace为false,根据原有的Series对象数据复制得到新的Sereis,对新的Sereis对象删除数据并将其返回 # s2 = s.drop('f') # display(s,s2) # inplace为True,删除的就是原有Sereis对象的数据,并且drop方法返回None # s2 = s.drop('f',inplace=True) # display(s,s2) # 删除多个值,drop s.drop(['a','f'],inplace=True) display(s)

DataFrame介绍

DataFrame类似数据库中数据表,多列构成,每列类型不同。 DataFrame二维数据类型,具有行,列索引。 DataFrame从每一列来看,是一个Series;从每一行来看,也是一个Sereis

DataFrame创建

我们可以使用如下方式创建DataFrame

二维数据结构类型(列表,ndarray数组,DataFrame等)字典类型,key列名,value为一维数组结构(列表,ndarray数组,Sereis等) # 使用二维的数据结构类型(ndarray,列表) # df = pd.DataFrame(np.array([[100,100,100],[90,90,90],[80,80,80]])) # df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]]) # # print(df) # display(df) # 使用字典创建,key就是列名,value一维数据结构 df = pd.DataFrame({'语文':[100,100,100],'数学':[90,90,90],'外语':[80,80,80]}) display(df) # 未通过index columns指定行索引和列索引,行索引和列索引默认从0开始 # index指定行索引 df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df)

DataFrame属性

indexcolumnsvaluesshapendimdtypes df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) # 返回行索引 display(df.index) # 返回列索引 display(df.columns) # 返回DataFrame对象对应ndarray数组 display(df.values) # 返回形状 display(df.shape) # 返回维度 display(df.ndim) # 返回各列数据类型 display(df.dtypes) # 通过index修改行索引信息 # df.index=['张三2','李四2','王五2'] # display(df) # 设置行索引和列索引名称 df.index.name='index-name' df.columns.name='columns-name' display(df) # 超过二维数据创建DataFrame 报错 df = pd.DataFrame(np.arange(18).reshape(2,3,3)) display(df)

DataFrame列操作

获取列数据

df[列索引]df.列索引

增加(修改)列

df[列索引]=列数据

删除列

del.df[列索引]df.pop(列索引)df.drop(列索引或数组) df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 获取列数据,通过df[列索引] # 注意,此种方式索引被解析成列索引,获取列数据,不会解析成行索引 # display(df['语文'],type(df['语文'])) # 获取多列数据, df[索引数组] display(df[['语文','数学']],type(df[['语文','数学']])) # 如果索引数组中索引只有一个列标签,返回的仍然是DataFrame类型 display(df[['语文']],type(df[['语文']])) # 第二种方式访问列数据,不推荐 display(df.语文) df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 增加、修改列 # 列标签不存在话,增加一列 # df['物理']=[80,80,80] # display(df) # 根据已有列计算,得到新的一列 df['总分']=df['语文']+df['数学']+df['外语'] display(df) # 列标签存在话,修改一列 # df['语文']=[80,80,80] # display(df) df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 删除列,采用类似字典方式 del pop # del df['语文'] # display(df.pop('语文')) # display(df) # DaraFrame提供drop方法删除, df.drop('数学',axis=1,inplace=True) display(df)

DataFrame行操作

获取行

df.loc 根据标签进行索引df.iloc根据位置进行索引

增加行

append

删除行

df.drop df = pd.DataFrame([[100,100,100],[90,90,90],[80,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # df.loc 标签索引 display(df.loc['张三'],type(df.loc['张三'])) # df.iloc 位置索引 # display(df.iloc[0]) # 多行获取 # display(df.loc[['张三','李四']]) # 增加行数据 # 创建一个Sereis对象,Sereis对象通过append方法加入到DataFrame中 # Sereis对象包含 value信息,index信息,name信息 newLine= pd.Series([85,85,85],index=['语文','数学','外语'],name='赵六') df = df.append(newLine) display(df) # 删除行数据 df.drop(['张三','李四'],axis=0,inplace=True) display(df)

DataFrame混合操作

先获取行,再获取列先获取列,再获取行 df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 先获取行,再获取列 # display(df.loc['张三'].loc['语文']) # display(df.loc['张三']['语文']) # display(df.loc['张三','语文']) # 先获取列,再获取行 display(df['语文'].loc['张三']) display(df['语文']['张三']) # 错误,不支持 # display(df['语文','张三'])

DataFrame结构

DataFrame的一行或一列,都是Sereis类型对象。对于行来说,Series对象name值就是行索引名称,元素值对应标签是列索引名称。对于列来说,Series对象name值就是列索引名称,元素值对应标签是行索引名称。

df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # display(df.loc['张三'],type(df.loc['张三'])) display(df['语文'],type(df['语文']))

DataFrame切片、布尔、标签数组索引

df[切片],对行操作;df[索引],对列操作布尔数组是对行操作标签数组是对列操作 df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 混合操作,列确定,对行切片 # display(df['语文'].loc['张三':'李四']) # display(df['语文'].iloc[0:1]) # 混合操作,行确定,对列切片 # display(df.loc['张三'].loc['语文':'数学']) # display(df.loc['张三'].iloc[0:1]) # 混合操作,对行切片,对列切片 # display(df.loc['张三':'李四']) # display(df.loc['张三':'李四'].loc['语文':'数学']) # display(df.loc['张三':'李四','语文':'数学']) # 仅对行进行切片操作 # display(df.loc['张三':'李四']) # display(df.iloc[0:1]) # 仅对列进行切片操作 # display(df['语文':'数学']) display(df.loc[:,'语文':'数学']) df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 一维布尔数组,对行进行操作,不是对列进行操作 # bArray=[True,True,False] # display(df[bArray]) # 二维布尔数组,对DataFrame的每一个元素进行运算,True保留,False值设置为NaN display(df>85) display(df[df>85]) df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 标签数组,对列进行操作 lArray = ['语文','数学'] display(df[lArray])

DataFrame运算

转置DataFrame之间运算,不但行索引要对齐,列索引也要对齐,否则产生空值。如果不想要空值,可使用DataFrame的函数代替运算符计算,通过参数fill_value参数指定填充值DataFrame和Series运算,默认Series索引匹配DataFrame列索引,然后进行广播。当然,我们可以通过axis参数,指定行索引匹配还是列索引匹配 df=pd.DataFrame(np.arange(1,5).reshape(2,2)) display(df,df.T) # DataFrame对象之间操作,行索引对应,列索引也对齐 # df = pd.DataFrame(np.ones((2,2))) # df2 = pd.DataFrame(np.ones((2,2))) # display(df,df2) # display(df+df2) # DataFrame对象之间操作,行索引,列索引不对齐 df = pd.DataFrame(np.ones((2,2))) df2 = pd.DataFrame(np.ones((2,2)),index=[1,2],columns=[1,2]) display(df,df2) # DataFrame对象之间行和列索引不对齐化,首先补齐行索引和列索引,数据填充NaN,然后再进行操作 display(df+df2) # 如果不想要运算结果为空值的话,就可以使用函数(add)来替换操作符(+),通过fill_value参数指定填充值 display(df.add(df2,fill_value=10)) # DataFrame和Sereis之间运算 df = pd.DataFrame(np.arange(1,5).reshape(2,2)) s = pd.Series([10,20]) display(df,s) # 默认Series对象标签和DataFrame的列 标签匹配,广播,再计算 display(df+s) # 设置Sereis对象标签和DataFrame的行标签匹配,广播,再计算 display(df.add(s,axis='index'))

过程分析图:

排序

索引排序

Sereis和DataFrame对象可以使用sort_index对索引进行排序。DataFrame还可以通过axis指定对行还是列索引进行排序,也可以通过ascending参数指定升序还是降序排序

值排序

Sereis和DataFrame对象使用sort_value方法进行值排序

# 索引排序 df = pd.DataFrame(np.arange(9).reshape(3,3),index=[3,1,2],columns=[6,4,5]) display(df) # 对行索引排序 # display(df.sort_index()) # 对列索引排序 # display(df.sort_index(1)) # inplace,True对原有的数据进行排序,sort_index返回None,False对拷贝得到的数据进行排序 # df.sort_index(inplace=True) # display(df) # ascending指定升降序,False降序,True升序 display(df.sort_index(ascending=False))

执行结果:

| | 6 | 4 | 5 | | ---- | ---- | ---- | ---- | | 3 | 0 | 1 | 2 | | 1 | 3 | 4 | 5 | | 2 | 6 | 7 | 8 |

| | 6 | 4 | 5 | | ---- | ---- | ---- | ---- | | 3 | 0 | 1 | 2 | | 2 | 6 | 7 | 8 | | 1 | 3 | 4 | 5 |

# df = pd.DataFrame([[100,100,100],[90,90,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) # display(df) # 对列数据, 比如对外语数据进行从小到大的排序 # df.sort_values('外语',axis=0,inplace=True) # display(df) # 对行数据,比如王五成绩按照从小到大排序 # display(df.sort_values('王五',axis=1)) # 对多列数据进行排序,比如对语文和数学进行排序,先对语文排序,语文相等,再根据第二列数学进行排序 df = pd.DataFrame([[100,100,100],[100,90,90],[100,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) display(df.sort_values(['语文','数学'],axis=0))

执行结果:

| | 语文 | 数学 | 外语 | | ---- | ---- | ---- | ---- | | 张三 | 100 | 100 | 100 | | 李四 | 100 | 90 | 90 | | 王五 | 100 | 80 | 80 |

| | 语文 | 数学 | 外语 | | ---- | ---- | ---- | ---- | | 王五 | 100 | 80 | 80 | | 李四 | 100 | 90 | 90 | | 张三 | 100 | 100 | 100 |

索引对象

Series、DataFrame的index或者DataFrame的columns都是是一个索引对象

索引对象可以像数组那样进行索引访问索引对象内容是不可修改 df = pd.DataFrame(np.arange(9).reshape(3,3)) display(df) # index和columns都是索引对象 display(df.index,type(df.index)) display(df.columns,type(df.columns)) index = df.index display(index[0]) # 不支持修改索引对象中内容 # index[0]=4 # 支持指向一个新的索引对象 index2 = pd.Index([4,5,6]) df.index = index2 display(df)

执行结果:

| | 0 | 1 | 2 | | ---- | ---- | ---- | ---- | | 0 | 0 | 1 | 2 | | 1 | 3 | 4 | 5 | | 2 | 6 | 7 | 8 |

RangeIndex(start=0, stop=3, step=1) pandas.core.indexes.range.RangeIndex RangeIndex(start=0, stop=3, step=1) pandas.core.indexes.range.RangeIndex 0

| | 0 | 1 | 2 | | ---- | ---- | ---- | ---- | | 4 | 0 | 1 | 2 | | 5 | 3 | 4 | 5 | | 6 | 6 | 7 | 8 |

统计相关方法

mean/sum/countmax/mincumsum/cumprodargmax/argminidxmax/idxminvar/std df = pd.DataFrame([[np.nan,np.nan,100],[100,100,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # 统计非NaN值的个数,默认按照列来统计,axis=1设置按照行统计 display(df.count()) display(df.count(axis=1))

执行结果:

| | 语文 | 数学 | 外语 | | ---- | ----- | ----- | ---- | | 张三 | NaN | NaN | 100 | | 李四 | 100.0 | 100.0 | 90 | | 王五 | 86.0 | 80.0 | 80 |

语文 2 数学 2 外语 3 dtype: int64 张三 1 李四 3 王五 3 dtype: int64 df = pd.DataFrame([[100,95,100],[95,100,90],[86,80,80]],index=['张三','李四','王五'],columns=['语文','数学','外语']) display(df) # idxmax返回数据最大值所对应的索引,默认按照列 # display(df.idxmax()) # # axis=1,设置按照行,找到每行最大值对应的索引 # display(df.idxmax(axis=1)) # idxmin回数据最小值所对应的索引,默认按照列 display(df.idxmin()) # axis=1,设置按照行,找到每行最小值对应的索引 display(df.idxmin(axis=1))

执行结果:

| | 语文 | 数学 | 外语 | | ---- | ---- | ---- | ---- | | 张三 | 100 | 95 | 100 | | 李四 | 95 | 100 | 90 | | 王五 | 86 | 80 | 80 |

语文 王五 数学 王五 外语 王五 dtype: object 张三 数学 李四 外语 王五 数学 dtype: object

最新回复(0)