Python大数据分析之数据处理
# -*- coding: utf-8 -*-
#1, read_table()读取txt文件
from pandas import read_table
df=read_table(r'D:\rz.txt',sep=" ")
'''查看前3条数据,默认是5条'''
print(df.head(3))
#2, read_csv()读取csv文件
from pandas import read_csv
df=read_csv(r'D:\rz.csv',sep=",")
print(df)
#3, read_excel()读取excel文件
from pandas import read_excel
#df=read_excel(r'd:\rz.xlsx',sheet_name='Sheet1')
#表示读取第一,第二个sheet页。
df=read_excel(r'd:\rz.xlsx',sheet_name=[0,1])
print(df)
#4, pymysql读取mysql
import pandas as pd
import pymysql
dbconn=pymysql.connect(host="",
database="",
user="",
password="",
port=3306,
charset='utf8')
sqlcmd="select * from table"
a=pd.read_sql(sqlcmd,dbconn)
dbconn.close()
b=a.head() #取前5条数据
print(b)
#5,to_csv()导出数据到csv文件
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64]),
'name':Series(['ben','john','jerry'])})
df.to_csv(r'd:\01.csv') #默认带上index
df.to_csv(r'd:\02.csv',index=False) #无index
#6,to_excel()导出数据到excel文件
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64]),
'name':Series(['ben','john','jerry'])})
df.to_excel(r'd:\01.xlsx') #默认带上index
df.to_excel(r'd:\02.xlsx',index=False) #无index
#7,to_sql导出数据到mysql
from pandas import DataFrame
from pandas import Series
from sqlalchemy import create_engine
#启动引擎,user:password是用户和密码,host:port是ip和端口,databasename是库名
engine=create_engine("mysql+pymysql://user:password@host:port/
databasename?charset=utf8")
df=DataFrame(
{'age':Series([26,85,64]),
'name':Series(['ben','john','jerry'])})
#存入mysql
df.to_sql(name='table_name',
con=engine,
if_exists='append',
index=False,
index_label=False)
#8,重复值的处理
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64,85,85]),
'name':Series(['ben','john','jerry','john','john'])})
#duplicated返回一个布尔型的Series,显示是否有重复行。
print(df.duplicated()) #默认判断全部列
print(df.duplicated('name')) #只判断name列是否重复
print(df.duplicated('age')) #只判断age列是否重复
print(df.drop_duplicates('age')) #去除重复项
#9,缺失值的处理
pandas使用浮点值NaN表示缺失数据,可使用.isnull和.notnull函数判断缺失。
1、dropna():去除数据结构中值为空的数据行。
2、fillna():用其他数值替代NaN,
如果使用method='pad'参数将使用前一个数据替代NaN,
如果使用method='bfill'参数将使用后一个数据值替代NaN,
如果使用df.mean()参数将使用平均数或者其他描述性统计量来代替NaN,
3、fillna({'列名1':值1, '列名2':值2}),传入一个字典,对不同列填充不同值。
4、strip():清楚字符型数据首尾的指定字符,默认为空格。lstrip删除首字符,rstrip删除尾字符
df['name'].str.strip()
#10,字段抽取,slice(start,stop),start是开始位,stop是结束位
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'序号':Series([1,2,3]),
'手机':Series([16612345678,18812346789,19912344567])})
newdf=df['手机'].astype(str) #将数值转化为字符串
bands=newdf.str.slice(0,3) #抽取手机号前3位,判断品牌
areas=newdf.str.slice(3,7) #抽取中间4位,判断号码地域
tell=newdf.str.slice(7,11) #抽取后4位
print(tell)
#11,字段拆分split(sep,n,expand=False)
#sep是分隔符,n是分隔后新增的列数,expand为True返回DataFrame,False返回Series
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'序号':Series([1,2,3]),
'IP':Series(['10.10.10.10','11.11.11.11','12.12.12.12'])})
df['IP'].str.strip() #IP先删除首尾空格
newdf=df['IP'].str.split('.',3,True) #按.分割,新增3列
newdf.columns=['IP1','IP2','IP3','IP4'] #设置列名
print(newdf)
#12,重置索引,指定某列为索引,便于对其他数据进行操作
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64,85,85]),
'name':Series(['ben','john','jerry','john','john'])})
df1=df.set_index('name') #以name列为新的索引
print(df1)
#13、记录抽取
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'序号':Series([1,2,3]),
'电话':Series([16612345678,18812346789,19912344567]),
'IP':Series(['10.10.10.10','11.11.11.11','12.12.12.12'])})
#按条件抽取,返回的都是DataFrame
print(df[df.电话==16612345678])
print(df[df.电话>16612345678])
print(df[df.电话.between(13400000000,18900000000)])
print(df[df.IP.isnull()])
print(df[df.IP.str.contains('10.',na=False)])
#14、随机抽样
#numpy.random.randint(start,end,num) 范围开始值、结束值、抽样个数
from pandas import DataFrame
from pandas import Series
import numpy
df=DataFrame(
{'age':Series([26,85,64,13,32,45,55,66,77,99]),
'name':Series(['ben','john','jerry','ab','cd','ef',
'gg','kk','rr','tt'])})
r=numpy.random.randint(0,10,3) #随机抽取3条记录,可以有重复,返回一个Series
print(r)
print(df.loc[r])
#15,通过索引名抽取数据
#loc[行标签,列标签],两个参数既可以是列表也可以是单个字符,如果都为列表,
#则返回的是DataFrame,否则为Series
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64,13,32,45,55,66,77,99]),
'name':Series(['ben','john','jerry','ab','cd','ef',
'gg','kk','rr','tt'])})
print(df.loc[0]) #抽取第1行数据,返回的是Series
print(df.loc[[0,2]]) #抽取第1行和第3行数据,行索引必须是列表的形式
print(df.loc[0:6]) #抽取第1行到第7行的数据
print(df.loc[0:6,'name']) #抽取name列的第1-7行数据
df=df.set_index('age') #更改age列为新的索引
print(df.loc[26:66]) #抽取两行之间的数据
#16,通过索引号抽取数据
#iloc[行索引号,列索引号]
from pandas import DataFrame
from pandas import Series
df=DataFrame(
{'age':Series([26,85,64,13,32,45,55,66,77,99]),
'name':Series(['ben','john','jerry','ab','cd','ef',
'gg','kk','rr','tt'])})
print(df.iloc[1,0]) #抽取第2行、第1列的值,返回的是单个值
print(df.iloc[[0,2],:]) #抽取第1行和第3行的数据
print(df.iloc[:,1]) #抽取第2列的所有数据
#17,抽取字典数据
#字典的key和value各作为一列
from pandas import DataFrame
from pandas import Series
d1={'a':'[1,2,3]','b':'[0,1,2]'}
a1=DataFrame.from_dict(d1,orient='index') #将字段转为dataframe
b1=a1.reset_indprint(b1)
b1.columns=['key','value'] #将列重命名为key和value
print(b1)
#字典的每一个元素作为一列,value的长度相同
d2={'a':[1,2,3],'b':[0,1,2]}
a2=DataFrame(d2)
print(a2)
#字典的每一个元素作为一列,value的长度不同
d3={'a':Series([1,2,3]),'b':Series([1,2,3,4])}
a3=DataFrame(d3)
print(a3)
#18,插入记录
import pandas as pd
df1=pd.DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]})
print(df1)
#抽取df1的index=1的行,并将第1列、2列、3列赋值为--
df2=pd.DataFrame({df1.columns[0]:"--",df1.columns[1]:"--",
df1.columns[2]:"--"},index=[1])
print(df2)
#注意df1.loc[:0]不能写成df1.loc[0],因为前者返回的是DataFrame,后者返回的是Series
df3=pd.concat([df1.loc[:0],df2,df1.loc[1:]])
print(df3)
df4=df3.reset_index(drop=True) #重置索引,并删除新索引
print(df4)
#19,修改记录
#整体替换
df['colname']=[1,2,3]或Series([])
#所有列的单值替换
df.replace('B','A') #用A替换B
#指定列的单值替换,用0替换"体育"列中的"作弊","军训"列中的"缺考"
df.replace({'体育':'作弊','军训':'缺考'},0)
#多值替换,用陈龙替换成龙,用小明替换小李
df.replace({'成龙':'陈龙','小李':'小明'})
#20,交换行或列
from pandas import DataFrame
df=DataFrame({'a':[1,2,3],'b':['a','b','c'],'c':["A","B","C"]})
print(df)
hang=[0,2,1]
df=df.reindex(hang) #交换行
print(df)
lie=['a','c','b']
df=df.reindex(columns=lie) #交换列columns=
print(df)
#交换两行
df.loc[[0,2],:]=df.loc[[2,0],:].values #交换index=0和index=2两行数据
print(df)
#交换两列
df.loc[:,['a','b']]=df.loc[:,['b','a']].values
print(df)
#两列中间插入一列
df['d']=[4,5,6] #先增加一列
print(df)
df.loc[:,['b','d']]=df.loc[:,['d','b']].values #交换两列的值
#交换两列的列名
lie=list(df.columns)
i=lie.index('b')
j=lie.index('d')
lie[i],lie[j]=lie[j],lie[i]
df.columns=lie
print(df)
#21,排名索引
#Series:sort_index(ascending=True)对index进行排序操作,True为升序
#DataFrame:sort_index(axis=0,by=None,ascending=True)
from pandas import DataFrame
df0={'Ohio':[0,6,3],'Texas':[7,4,1],'California':[2,8,5]}
df=DataFrame(df0,index=['a','d','c'])
print(df)
print(df.sort_index())
print(df.sort_index(by='Ohio')) #by针对某列进行升序排序
print(df.sort_index(by=['California','Texas']))
print(df.sort_index(axis=1)) #axis=1按横轴排序,axis=0按纵轴排序
#rank(method='average',asceding=True)把对象的values替换成名次(从1到n)
#mothod有4个可选项,average、min、max、first
from pandas import Series
ser=Series([3,2,0,3],index=list('abcd'))
print(ser)
print(ser.rank())
print(ser.rank(method='min'))
print(ser.rank(method='max'))
print(ser.rank(method='first'))
#22,数据合并
#记录合并:df2合并到df1中,为True则index顺延
df=pandas.concat([df1,df2],ignore_index=True)
df.append(df2,ignore_index=True)
#字段合并
from pandas import DataFrame
import pandas
df=DataFrame({'col1':['133','166','188'],
'col2':['0351','0354','0713'],
'col3':['2190','8513','0615']})
print(df['col1']+df['col2']+df['col3'])
#字段匹配
'''
merge(x,y,left_on,right_on)
x表示第一个数据框,y表示第二个数据框,left_on表示第一个数据库用于匹配的列
right_on表示第二个数据框用于匹配的列。
'''
df1=DataFrame({'学号':[1,2,3,4,5],
'姓名':['张三','李四','王五','赵四','胡胡']})
df2=DataFrame({'学号':[1,2,4,5,6],
'电话':['13312345678','16612345678',
'18812345678','19912345678','17712345678']})
df3=pandas.merge(df1,df2,left_on='学号',right_on='学号')
print(df3)
#类似数据库的右连接,how还有inner,outer,left,right四种
df4=df1.merge(df2,on='学号',how='right')
print(df4)
#23,数据计算
from pandas import DataFrame
import pandas
df=DataFrame({'姓名':['小李','小红','小明','胡胡'],
'语文':[90,80,60,20],
'数学':[60,70,99,100]})
df['总分']=df['语文']+df['数学']
print(df)
print(df.shape)
#24,数据分组
'''
cut(series,bins,right=True,labels=NULL)
series要分组的数据
bins分组的依据数据,必须是从小到大递增
right分组的时候右边是否闭合
labels分组的自定义标签
'''
bins=[min(df.语文)-1,60,70,80,max(df.语文)+1]
lab=["不及格","及格","良好","优秀"]
demo=pandas.cut(df.语文,bins,right=False,labels=lab)
print(demo)
#25,日期处理
#日期转换:to_datetime(string,format)
#format格式有%Y,%m,%d,%H,%M,%S 年-月-天-时-分-秒
from pandas import to_datetime
from pandas import DataFrame
from datetime import datetime
df=DataFrame({'no':[1,2,3],
'date':['2016/6/1','2017/6/1','2018/6/1']})
df_dt=to_datetime(df.date,format="%Y/%m/%d")
print(df_dt)
#日期格式化:
'''
apply(func,axis=0,arg=(),**kwds),将函数func应用到DataFrame行或列,axis=0
表示按列运算,axis=1表示按行运算。apply常和lambda函数一起使用。
datetime.strftime(x,format)
'''
df_str=df_dt.apply(lambda x:datetime.strftime(x,"%Y/%m/%d"))
print(df_str)
df1=DataFrame({'ohio':[1,3,6],'texas':[1,4,5],'california':[2,5,8]},
index=['a','c','d'])
print(df1)
f=lambda x:x.max()-x.min()
print(df1.apply(f))
#日期抽取
'''
data_dt.dt.property,property有以下几种:
second表示1~60秒
minute表示1~60分
hour表示1~24小时
day表示1~31日
month表示1~12月
year表示年
weekday表示1~7
'''
print(df_dt)
print(df_dt.dt.year)
print(df_dt.dt.day)
print(df_dt.dt.month)