Pandas

酥酥 发布于 2021-09-18 959 次阅读



1.序列与数据框

构造一个序列有以下几个方式:

  • 通过同质的列表或元组创建

  • 通过字典创建

  • 通过Numpy的一维数组创建

  • 通过数据框DataFrame中的某一列创建

				
					import pandas as pd
import numpy as np
gdp1=pd.Series([2.8,3.01,8.99])
gdp2=pd.Series({'北京':123,'上海':'233','宁波':'1234'})
gdp3=pd.Series(np.array((2.9,3.01,8.99)))
print(gdp1)
print(gdp2)
print(gdp3)
				
			

以上样例展示的是通过Series将列表、字典和一维数组转换为序列的过程,我们可以发现,通过列表、元组、一维数组创建的序列之前的第一列是自动编号的,而通过字典创建的序列是把索引放在第一列,字典值放在第二列。

一维数组跟序列有极高的相似性所以通过下标索引数组的方式同样适用于序列例如gdp1[0,1]可以取出gdp1中第1,2个元素。通过字典的键和通过行号来获得的行值是一样的。

另外,如果是对序列进行数学函数的运算,一般首选numpy模块,因为pandas在这一块比较欠缺;如果是对序列做统计运算,既可以使用numpy模块中的函数,也可以使用序列的方法,一般来说序列的方法更加优秀因为它更加丰富,如序列的偏度,峰度等,Numpy中没有这样的函数。

构造一个数据框有以下几种方式:

  • 通过嵌套的列表或元组创建

  • 通过字典构造

  • 通过二维数组构造

  • 通过外部数据的读取

				
					#构造数据框
df1=pd.DataFrame([['张三',1],['李四',2],['王二',3]])
df2=pd.DataFrame({'姓名':['张三','李四','王二'],'年龄':[1,2,3]})
df3=pd.DataFrame(np.array([['张三',1],['李四',2],['王二',3]]))
print(df1)
print(df2)
print(df3)
				
			

如果是通过列表元组或者二维数组的方式创建数据框,我们可以发现数据框是没有具体的变量名的,但通过字典方式创建时我们可以发现是有列表名的,所以如果需要手工构造数据框的话一般首选字典方法。

2.外部数据的读取

文本文件的读取

可以使用Pandas模块中的read_table或read_csv来实现对txt,csv文件的读取。注意这里的或并不是指每个函数只能读取一种格式的数据,而是这两种函数均可以读取文本文件的数据。

				
					import pandas as pd
pd.read_table(filepath_or_buffer=,sep='\t',header='infer',names=None,index_col=None,usecols=None,dtype=None,converters=None,skiprows=None
              ,skipfooter=None,nrows=None,na_values=None,skip_blank_lines=True,parse_dates=False,thousands=None,comment=None,encoding=None)#pd.read_csv同理
'''
filepath_or_buffer:指定txt文件或csv文件的具体路径
sep:指定原数据集中各字段之间的分隔符,默认为Tab制表符
header:是否需要将原数据集中第一行作为表头,默认将第一行用作字段名称
names:如果原数据中没有字段,可以通过该参数在数据读取时给数据框添加具体的表头
index_col:指定原数据集中的某些列作为数据框的行索引
usecols:指定需要读取原数据集中的哪些变量名
dtype:读取数据时,可以为原数据集的某些字段设置不同的数据类型
converters:通过字典格式,为数据集中某些字段设置转换函数
skiprows:数据读取时,指定需要跳过原数据集开头的行数
skipfooter:数据读取时,指定需要跳过原数据集末尾的行数
nrows:指定读取数据的行数
na_values:指定原数据集中哪些特征的值作为缺失值
skip_blank_lines:读取数据时是否需要跳过元原数据中的空白行,默认为True
parse_date:如果为Ture,尝试解析数据框中的行索引是否为日期,必要时合并。
thousands:指定原数据集中的千分位符
comment:指定注释符,如果行首碰到注释符则跳过该行
encoding:文件中含有中文则可能需要指定字符编码
'''
user_income=pd.read_table(r'C:\user\Administrator\Desktop\data.txt',sep=',',parse_dates={'birthday':[0,1,2]},skiprows=2,
				
			

Excel文件的读取

				
					#Excel
pd.read_excel(io=,sheet_name=0,header=0,shiprows=None,skipfooter=0,index_col=None,names=None,parse_dates=False,
              parse_cols=None,na_values=None,thousands=None,convert_float=True)
'''
io:指定excel文件的具体路径
sheet_name:指定excel第几个表格可以通过下标也可以通过表名来索引
header:是否需要将原数据集中第一行作为表头,默认将第一行用作字段名称
skiprows:数据读取时,指定需要跳过原数据集开头的行数
skipfooter:数据读取时,指定需要跳过原数据集末尾的行数
index_col:指定原数据集中的某些列作为数据框的行索引
names:如果原数据中没有字段,可以通过该参数在数据读取时给数据框添加具体的表头
parse_cols:指定需要解析的字段
parse_date:如果为Ture,尝试解析数据框中的行索引是否为日期,必要时合并。
usecols:指定需要读取原数据集中的哪些变量名
na_values:指定原数据集中哪些特征的值作为缺失值
thousands:指定原数据集中的千分位符
convert_float:默认将所有的数值型字段转换为浮点型字段
converters:通过字典格式,为数据集中某些字段设置转换函数
'''
child=pd.read_excel(io='C:\user\Administrator\Desktop\data.xlsx',header=None,converters={0:str},names={'Id','Name','Color'})
				
			

数据库的读取

				
					import pymysql
import pymssql
pymysql.connect(host=None,user=None,password='',database=None,port=0,charset='')
pymssql.connect(server=None,user=None,password='',database=None,charset='')
'''
host(mssql中的server):指定要连接到的服务器
user:数据库用户名
password:数据库密码
database:数据库名
port:数据库的端口号
charset:指定读取数据库的字符集,若存在中文可能需要设置
'''
import pymysql
db=pymysql.connect('localhost','root','cba4579136','example')
cursor=db.cursor()
cursor.execute('delete from emp where empno=2')
db.commit()
#for i in cursor.fetchall():    #返回的是一个一个元组类型,fetchall是
    #print(i)
db.close()

#法二
user=pd.read_sql('select * from emp',db)
db.close()
user

#对于数据库的操作对象user可以有以下一些方法
user.head()#返回读取的前五行
user.tail()#返回读取的后五行
user.shape#查看数据的行列数
user.dtypes#查看每个数据集的数据类型
user.describe()#查看所有变量的统计值情况
pd.to_datetime()#方法可以将变量更改为日期型数据
#astype方法可以直接修改数据类型
user.reset_index()#可以把行索引转换为变量
				
			

数据清洗与整理

				
					#以下这段代码供各位参考,按条件对数据表进行修改的操作
import pandas as pd
'''

df=pd.read_excel('C:\\user\\Administrator\\Desktop\\data.xlsx')
df.dtypes#各变量数据类型
df.birthday=pd.to_datetime(df.birthday,format='%Y/%m/%d')#日期格式转换
df.tel=df.tel.astype('str')#将手机号转换为字符串
#新增年龄工龄两列
df['age']=pd.datetime.today().year-df.birthday.dt.year
df['workplace']=pd.datetime.today.year-df.start_work.dt.year
df.tel=df.tel.apply(func=lambda x:x.replace(x[3:7],'****'))##隐藏手机号码中间四位
df['email_domain']=df.email.apply(lambda x:x.split('@')[1])#取出邮箱域名
df['profession']=df.other.str.findall('专业:(.*?)')#取出专业信息
df.drop(['birthday','start_work','other'],axis=1,inplace=True)#去除无用的变量
df.head()
'''

#日期处理
dates=pd.to_datetime(format=)#设置格式,利用format参数
dates.dt.date#返回日期
dates.dt.quarter#返回季度
dates.dt.dayofyear#年中第几天
dates.dt.weekofyear#年中第几周
dates.dt.weekday_name#具体周几名称
dates.dt.day_in_month#月中多少天
dates.dt.year#年
dates.dt.day#日
dates.dt.minute#分
dates.dt.time#时间
dates.dt.second#秒
dates.dt.month#月
				
			

特殊情况处理

				
					#重复观测处理
df=pd.read_excel('C:\\user\\Administrator\\Desktop\\data.xlsx')
df.duplicated()#返回每一行的检测结果,即10行就会有10个布尔值
#配合any可以得到最直接的结果
any(df.duplicated())#any中只要有一个True总体就为True
#删除重复项
df.drop_duplicates(inplace=True)#inplace表示直接在原数据值上操作


#缺失值处理,在python中表现为NaN
df.isnull#可以用来判断是否存在缺失值但同理也是只能一行行判断
any(df.isnull)#可以得到一个如以上样例的放回结果,存在NaN值即为True
#删除法之记录删除
df.dropna()  #把有缺失值的行删除
#删除法之变量删除
df.drop('',axis=)  #缺失值较多的变量删除
#替换法之前向替换
df.fillna(method='ffill')#用缺失值的前一个值代替NaN
#替换法之后向替换
df.fillna(method='bfill')#用缺失值的后一个值代替NaN
#替换法之常数替换
df.fillna(value=0)
#替换法之统计值替换
df.fillna(value={'gender':df.gender.mode()[0]})

#异常值处理  异常值x满足Q1-1.5IQR<x<Q3+1.5*IQR  Q1是上四分位数,Q3是下四分位数
#或标准差检验法outlinear>abs(mean(x) +/- nσ) n=2为异常值,n=3为极端异常值
xbar=df.counts().mean()
xstd=df.counts().std()
any(df.counts>xbar+2*xstd)
any(df.counts>xbar+2*xstd)
#霜箱图判断法
Q1=df.counts.quantile(q=0.25)
Q3=df.counts.quantile(q=0.75)
IQR=Q1-Q3
any(df.counts>Q3+1.5*IQR)
any(df.counts<Q1-1.5*IQR)
				
			

数据子集的提取

				
					#以下三种索引方式与数组方式相同都是从零开始,无法取到上限
df1.iloc[2:4,[0,2]]#只能通过行索引、列标签
df1.loc[df1.gender=='男',[0,2]]#可以指定的行标签、列标签、字段名
https://blog.csdn.net/yoonhee/article/details/76168253
				
			

透视表函数

				
					#透视表函数
pd.pivot_table(data=,values=None,index=None,columns=None,aggfunc'mean'=,fill_value=None,margins=False,dropndataa=True,margins_name='All')
#data:指定需要构造透视表的数据集
#values:指定需要拉入'数值'框的字段列表
#index:定制需要拉入'行标签'框的字段列表
#columns:指定需要拉入'列标签'框的字符列表
#aggfunc:指定数值的统计函数,默认为统计均值,也可以指定numpy模块中的其他统计函数
#fill_value:指定一个标量,用于填充缺失值
#margins:bool型参数,是否需要显示行或列的总计值,默认为False
#dropna:bool型参数,是否需要删除整列为缺失的字段,默认为True
#margins_name:指定行或列的总计名称,默认为ALL
				
			

合并与连接

				
					#合并函数concat
pd.concat(objs=,axis=,join='outer',join_axes=None,ignore_index=,keys=None)
#objs:指定需要合并的对象,可以是序列、数据框或面板数据构成的列表
#axis:指定需要合并的轴,默认为0,表示合并多个数据的行,如果为一就表示合并多个数据的列
#join:指定合并的方式,默认为outer,表示合并所有数据,如果改为inner,表示合并公共部分的数据
#join_axes:合并数据后,指定保留的数据轴
#ignore_index:bool类型的参数,表示是否忽略原数据集的索引,默认为False,如果设为True就表示忽略原索引并生成新索引
#keys:为合并后的数据添加新索引,用于区分各个数据部分

#连接函数merge()
pd.merge(left=,right=,how='inner',on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False,suffixes=('_x','_y'))
#left指定需要连接的主表
#right:指定需要连接的辅表
#how:指定连接方式,默认为inner内连,还有其他选项,如左连left、右连right和外连outer
#on:指定连接两张表的共同字段
#left_on:指定主表中需要连接的共同字段
#right_on:指定辅表中需要连接的共同字段
#left_index:bool类型参数,是否将主表中的行索引用作表连接的共同字段,默认为False
#right_index:bool类型参数,是否将辅表中的行索引用作表连接的共同字段,默认为False
#sort:bool类型参数,是否对连接后的数据按照共同字段排序、默认为False
#suffixes:如果数据连接的结果中存在重叠的变量名,则使用各自的前缀进行区分
				
			

分组聚合

				
					#分组聚合操作(效果相当于数据库中的group by分组)
group=df1.groupby(by={'color','cut'})#分组方法
result=group.aggregate({'color':np.size,'carat':np.min})#对不同变量进行统计汇总