Day 078 Pandas

Pandas

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

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

安装与使用

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

两个常用数据类型

pandas提供两个常用数据类型

  • Series
  • DataFrame
        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属性

  • index
  • columns
  • values
  • shape
  • ndim
  • dtypes
        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'))
      

过程分析图:


v2-3c40829a650f96ab57be6975d78f8601_b.jpg


排序

索引排序

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/count
  • max/min
  • cumsum/cumprod
  • argmax/argmin
  • idxmax/idxmin
  • var/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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值