Pandas
Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型
-
Pandas 是 Python 语言的一个扩展程序库,用于数据分析。
-
Pandas 是一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析工具。
-
Pandas 名字衍生自术语 "panel data"(面板数据)和 "Python data analysis"(Python 数据分析)。
-
Pandas 一个强大的分析结构化数据的工具集,基础是 Numpy(提供高性能的矩阵运算)。
-
Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。
-
Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。
1.0 Series构造
Series是一种类似于字典(dict-like)的一维数组(array-like)的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
构造Series
pandas.Series(data=None,index=None)
ndarray 构造Series
1) From ndarray 使用ndarray构造 # 是一个引用对象(共用一个内存数据,数据变更相互影响)
List 构造Series
2) From List 使用列表构造 # 是一个副本对象(copy一个新内容,数据变更互不影响)
Dict 构造Series
3) From dict 使用字典构造 # 一般不用指定index,因为dict中的key做为Series的显示索引低于index的优先级值会显示NaN
value 构造 Series
4) From scalar value 使用value构造 # 使用一个标量(常量或变量)构造时,必须指定index,标量会被重复匹配到每一个index
1.1 Series属性
- name 返回Series对象的名字 # name表示列名
- shape 返回Series对象的形状 # shape表示形状维度
- size 返回Series对象的元素个数 # size表示元素个数
- index 返回Series对象的显示索引 # index返回所有索引
- values 返回Sereis对象的所有元素值 # values返回所有值
1.2 Series的数学运算
Series对大多数NumPy的函数都是兼容的
1) 与非pandas对象运算
服从广播机制原则
2) NumPy functions
3) Series之间运算
- 索引对齐原则
- 对不齐补空值, 使用add\sub\mul\div函数处理空值
2.0 DataFrame
DataFrame是一个二维的表格型数据结构,可以看做是由Series组成的字典(共用同一个索引)。
DataFrame由按一定顺序排列的【多列】数据组成,每一列的数据类型可能不同。
设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values(numpy的二维数组)
2.1 DataFrame 构造
DataFrame 列与列之间可以是不同类型。
pandas.DataFrame() #data=None 用于构造DataFrame数据;index=None;columns=None, 行列索引;dtype=None, 数据类型;copy=False,当data参数是dict字典类型时,需要指定index数值,因为dict无序列,也可以在dict外加 [ ] 列表解决
1) From dict of Series or dicts 使用一个由Series构造的字典或一个字典构造
2) From dict of ndarrays / lists 使用一个由列表或ndarray构造的字典构造ndarrays必须长度保持一致
3) From a list of dicts 使用一个由字典构成的列表构造
4) DataFrame.from_dict() 函数构造
names = ['张三','李四','王五','赵六','老王']
yuwen = np.random.randint(0, 100, size=5)
shuxue = np.random.randint(0, 100, size=5)
display(names, yuwen, shuxue)
dictionary = {
'names':names,
'语文':yuwen,
'数学':shuxue
}
score = pd.DataFrame(data=dictionary)
2.2 DataFrame属性
- dtypes
- values
- index
- columns
df.dtypes # 表示查看df内各列类型
df.values # 表示查看所有数据值
df.index # 查看行标签
df.columns # 查看列标签
2.3 DataFrame运算
DataFrame和Series运算,默认就是列索引对齐原则
1) 与非pandas对象运算 # 序列必须相同
2) 与Series对象运算 # DataFrame和Series运算,默认就是列索引对齐原则
3) 与DataFrame对象运算
- 索引对齐原则(row\columns)
- 对不齐补空值, 使用add\sub\mul\div函数处理空值
Python 操作符与pandas操作函数的对应表
参数fill_value表示未对应的值用什么填充默认Nan。
fill_value不支持DataFrame和Series之间的运算
df1.add(other, axis='columns', level=None, fill_value=None) # axis默认columns或1,可以改为index或0,fill_value表示多余的值用‘Nan’填充计算
4) NumPy functions
5) 转置运算
df1.T # 转置数组
2.4 Pandas 访问
Basics标准访问形式
Object Type | Indexers |
---|---|
Series | s.loc[indexer] |
DataFrame | df.loc[row_indexer,column_indexer] |
1) 使用Labels访问 loc[] 显示访问
# 显示访问
loc[] 显示访问:在pandas对象中,可以使用标签的形式访问数据
s.loc[labels]
df.loc[row_labels, col_labels]
labels: 标签名, 标签名列表, BOOL列表(没有标签的,有标签),条件表达式, 切片(闭合区间)
2) 使用indexer隐式访问 iloc[] 隐式访问
# 隐形访问
iloc[] 隐式访问:在pandas对象中,也可以使用index的形式访问数据
s.iloc[index]
df.iloc[row_index, col_index]
index: index, index_list, bool_list, 条件表达式, 切片(左闭右开)
tips: 使用索引切片的都是左闭右开, 使用标签切片的都是闭合区间
tips:直接用中括号访问,标签访问的是列 标签切片的是行
3) 间接访问(不提倡)
df.loc[1].loc['A'] # 这种访问方式属于间接访问,不提倡
2.5 pandas高级查找
# 高级查处函数
1)where() # 满足con条件的保留,其他用other填充
2)mask() # 不满足con条件的保留, 其他用other填充
3)query() # 条件语句查询.只返回满足条件的行或列
4) filter() # 对行名和列名进行筛选,使用items选择行、列名称,配合axis,使用regex正则表达式,模糊匹配名称
2.6 pandas聚合操作
Function | Description | 备注 |
---|---|---|
count | Number of non-NA observations | 个数 |
sum | Sum of values | 求和 |
mean | Mean of values | 均值 |
mad | Mean absolute deviation | 绝对值均值 |
median | Arithmetic median of values | 中位数 |
min | Minimum | 最小值 |
max | Maximum | 最大值 |
mode | Mode | 众数 |
abs | Absolute Value | 绝对值 |
prod | Product of values | 乘积 |
std | Bessel-corrected sample standard deviation | 标准差 |
var | Unbiased variance | 方差 |
quantile | Sample quantile (value at %) | 分位数 |
cumsum | Cumulative sum | 累和 |
cumprod | Cumulative product | 累积 |
# DataFrame默认是列方向的聚合
# pandas自动忽略空值
2.7 单层索引和多层级索引
索引类型大致分布如下:
# RangeIndex : Index implementing a monotonic integer range.
# CategoricalIndex : Index of :class:`Categorical` s.
# MultiIndex : A multi-level, or hierarchical, Index.
# IntervalIndex : An Index of :class:`Interval` s.
# DatetimeIndex, TimedeltaIndex, PeriodIndex
# Int64Index, UInt64Index, Float64Index
怎么使用索引:
pd.Index是pandas提供的专门用于构造索引的类,它有很多子类,CategoricalIndex, RangeIndex等
所有的子类都具备Index类的特点,比如可以使用索引访问元素
通常如果需要对索引定制(name),可以使用pd.Index系列方法来构造索引
如果没有特殊需求,使用普通的列表完全没有问题
1)单层索引
# 单层索引
pd.Index(data=None,dtype=None,copy=False,name=None,tupleize_cols=True,**kwargs,) # name:表示索引名就是索引这列的名称。
2) 多层索引构建
# product乘积构建
pd.MultiIndex.from_product(iterables,sortorder=None) # product乘积构建参数需要传入一级索引和二级索引
level1 = ['第一期','第二期']
level2 = ['A','B','C']
columns = pd.MultiIndex.from_product([level1,level2], names=['期数','产品'])
index = pd.Index(data=['张三','李四','王五'], name='销售员')
data = np.random.randint(0, 100,size=(3,6))
df = pd.DataFrame(data=data, index=index, columns=columns)
# arrays法(必须是一个二维数组结构)
pd.MultiIndex.from_arrays() # # 可以直接作为多层索引使用,不需要构造MultiIndex对象
columns = pd.MultiIndex.from_arrays([['第一期', '第一期', '第一期', '第二期','第二期','第二期'],
['张三','李四','王五','张三','李四','王五']])
index = list('ABC')
data = np.random.randint(0, 100, size=(3, 6))
pd.DataFrame(data=data, index=index, columns=columns)
# tuple 法
pd.MultiIndex.from_tuples() #
index = pd.MultiIndex.from_product([['第一期','第二期'], ['张三','李四','王五']], names=['期数','销售员'])
columns = pd.Index(data=['A','B','C'], name='产品名称')
data = np.random.randint(0, 100, size=(6,3))
df = pd.DataFrame(data=data, index=index, columns=columns)
2.8 多层索引访问
1)显示索引
df.loc[row_labels, col_labels]
s.loc[labels]
labels: 标签名称 标签名称列表 条件表达式(bool) 切片
总结:
多层索引的访问逻辑,与单层索引的访问逻辑完全一致
但是,多层索引的索引表达形式是以元组的方式处理的
【注意】可以从外层索引开始,一级一级的向内层访问,但是不能越级访问
【注意】切片 索引必须要先排序, 切片要先将索引进行从小到大的排序 df.sort_index()
2)隐形索引
df.iloc[] # 与行列标签无关,只与数据有关,数据第一行为0,以此类推
3)Stack和Unstack
# unstack把行索引向列索引变换
# stack 把列索引向行索引变换
df.unstack(level=1)
3.0 Pandas 数据处理
3.1 数据IO操作
pandas IO操作主要是读取有特定格式的文件
# 文件读取
open('路径',mode='模式',encoding='utf-8',errors='ignore') # errors='ignore' 打开文件可以忽略一些解码错误
pd.read_csv('路径', sep=',' , header=0, index_col=None,names=None) # sep=','表示数据默认用‘,’分割,header=0表示默认将第一行数据做为列标签,可以改为None;index_col表示行标签默认为None,names表示为列标签更改列名.
pd.read_table('路径',sep='\t') # sep='\t'默认是\t。
pd.read_excel('路径',sheet_name=0) # sheet_name表示指定读区那张表可以直接输入表名或隐形索引数
sep='\s+' # 可以分割多个空格
# 文件保存
df.to_csv('表名') #保存数据xx为需要保存的数据。
3.2 数据探索
# 查看数据数值
pd.describe() # 返回每一列数值类型数据结构,参数percentiles=[0.25,0.99]可以用来查看99%的数据和最大值之间的差异,差异越大异常数据存在率越高。
# 查看列属性
pd.info() # 返回每列的标签、数据个数、每列数据类型和文件大小。
#查看前五行数据
pd.head() # 默认查看数据前五行
# 查看后五行数据
pd.tail() # 默认查看数据后五行
#随机查看10行数据
pd.sample() # 随机返回10行数据
3.3 空值处理
1) None
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。
object类型的运算要比int类型的运算慢得多
2) np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
在numpy中,可以使用np.nanxxx()函数来计算nan,此时视nan为0。
object 运算效率 低于 float
numpy 提供第一个常量,用于表达空值,是一个float
NaN(not a number) #符号,不是一个量, pandas对象中,所有的np.nan None 显示的时候,都是以NaN显示
NaT (not a time) # 同上
pandas自动把None处理成np.nan
3.4 空值查找
# 查找Nan值
isnull() #返回bool类型的DataFrame,一般情况isnull()会和any()共同使用,any()查看一个bool列表中, 是否存在至少一个True
# 查找不上Nan的值
notnull() #返回bool类型的DataFrame,一般情况isnull()会和all()共同使用,all()查看一个bool列表中, 是否存全为True
3.5 空值填充
# 对全表Nan值进行填充
df.fillna(value='特定值',) # 对整个表格中的统一填充方法,value='特定值')覆盖NaN
df.fillna(method='backfill或ffill',axis=1,limit=1) # method表示用周围值覆盖NaN值,backfill表示用后部数据覆盖,ffill表示用前面数据覆盖(向靠近行标签或列标签方向覆盖为后部数据覆盖backfill,向远离行标签或列标签为前面数据覆盖ffill)limit表示覆盖几次,默认为一直覆盖(多Nan在一起)
# value和backfill只能同时使用一个
3.6 空值过滤
# 聚合法过滤空值
结合isnull notnull any all 来确定一个条件,然后再利用loc访问,实现过滤
df.loc[df.notnull().any(axis=1)]
# 过滤空值
df.dropna(axis=0,how='any或all',subset=['列名1','列名2'],inplace=False) # axis默认为0,how=‘any’表示删除出现NaN的行或列,how=‘all’表示删除全部行或列为NaN的值,subset表示只修改subset选择的列,inplace是否覆盖原数据
3.7 异常值处理
# 删除指定索引的值
# index <==> labels axis=0
# columns 指定列索引 <==> labels axis=1
df.drop(labels='',) # index参数等于labels参数加上axis=0参数,columns参数等于 labels参数加上axis=1。
# 数据异常方向过滤方法
数据异常一般使用方法为正太分布的3倍std(标准差)方法和使用上四中位数和下四中位数进行异常值判定
# 重复值处理
步骤:1.检查 2.过滤 3.删除
# 检查重复值
df.duplicated(subset=[列名],keep='first') #subset参数表示需要检查的列,keep=‘first’保留首次出现的重复值,last保留最后出现的重复值
# 删除重复值
df.drop_duplicated(subset=[列名],keep='first')
3.8 Pandas排序
# 指定多条件index排序
df. sort_index(by=[标签],ascending=Trou) # 指定索引排序
# 指定多条件values排序
df. sort_values(by=[标签],ascending=Trou) # by指定的标签列或行,ascending=True默认升序,False降序
# 随机取出行或列
df.sample(n=5,axis=1) # n表示指定行数或列数
# 取出行或列
df.take([1,1,2,3],axis=1) # 取出指定行或列(可行列多取)
3.9 索引设置
# 把指定字段设置为索引
df.set_index(keys=['列标签']) # 将指定字段设置为索引
# 把指定索引设置为字段
df.reset_index(level=-1) #将索引设置为字段
# 按照指定的索引,进行索引重置(如果原始索引中存在,则选择,如果不存在,则空值填充)
df.reindex(labels=['索引'],axis=1) # 重置索引顺序
# 多层索引的删除
df.droplexel(level=-1,axis=0) # level 指定要删除的索引层级
3.10 映射处理
# 对标签进行映射
df.rename(mapper={},axis=0或1) # mapper参数可以传入dict和func,也可以直接指定index或者colums。
# 对数值进行映射
df.replace(to_replace=[数值,数值],value=[映射值,映射值]) #to_replace可以是列表,字典,正则等方法
# 只对一列数据进行映射
map支持Series对象,可以模糊匹配或精确匹配
df.A.map('arg, na_action=None') # arg参数需要传入func,
3.11 Pandas级联、合并
级联语法的核心就是索引对齐
级联的应用场景:不同期,但是结构相同的数据汇总
object 对象 array-like 可以是列表 ,也可以是元组
axis = 0 列索引对齐, axis=1 行索引对齐
# 级联
df.concat([df1,df2],axis=0) # veify_integrity=True参数是校验是否有重复索引,keys=[]参数添加多层索引,name对多层索引命名,ignore_index=True表示重置索引命名,join='outer'或‘inner’参数oiter保留所有标签,inner保留共有标签
# 合并
合并最多只能支持两张表的操作
合并是将多张表根据一个共同元素组合为一张表
pd.merge(left=df1,right=df2)
#left:参数表示左表 right:参数表示右边
#on:表示指定相同列进行合并 suffiexes:参数为没有参与合并的列指定一个后置
left_on:指定左表合并的字段 right_on:指定又表合并的字段 #一般用与字段名不同但是数据可以合并的列
how: inner 合并列取交集 outer合并列取并集 left 合并只取左表数据内容 right只取右边数据内容
left_index\right_index: 当左右表需要使用行索引作为合并列时,True
# 分组
# 分组必集合
df.groupby(by=['字段'])
# 转置行为列索引
df.unstack(level=-1) # 转置行索引为列索引level=-1位一级索引-2为二级索引
# 转置列为行索引
df.stack(level=-1) # 转置列索引为行索引level=-1位一级索引-2为二级索引
#多组分别聚合
df.agg({'字段':np.sum}) ## agg 接收一个字典对象 字典对象里:键是要聚合的列名称, 值是一个函数名字(地址),是一个聚合函数
# 高级聚合
# df.groupby('字段')['字段'].mean()
#df.groupby('字段')['字段'].apply(np.mean)
上面结果是一样的
# 对于分组对象而言,apply传递的函数,接收到的参数x是一组数据
# 交叉表
#显示交叉表
pd.crosstab(xindex=df[字段],columns=df[字段])
# index 是一个序列,而不是一个列标签
# 透视表
# 显示透视表
pd.pivot_table(data=df, index='字段', columns='字段',values=['字段'],aggfunc=np.mean)
# data 数据源 就是要进行透视的DataFrame对象
# index\columns 透视表的行列是从数据源的哪列提取的
# values 是要统计的数据源中的字段
# aggfunc 是聚合方法,传递的是函数名字