首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python之数据规整化:清理、转换、合并、重塑

斑点鱼又学完了一章,来分享啦~共勉之~主要涉及这几个函数:merge、concat、stack、unstack、join、get_dummies、qcut、compile、split、match、findall等

一、合并数据集

pandas.merge

pandas.concat

1.数据库风格的dataframe合并

%多对一

df1=pd.DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})

df1

df2=pd.DataFrame({'key':['d','b','a'],'data2':range(3)})

df2

pd.merge(df1,df2)#此处没有指定用哪个列进行连接,默认将重叠列名'key'当做键,类似 inner join,取交集

pd.merge(df1,df2,on='key')

pd.merge(df1,df2,how='outer')#取并集

df3=pd.DataFrame({'key1':['b','b','a','c','a','a','b'],'data1':range(7)})

df3

df4=pd.DataFrame({'key2':['d','b','a'],'data2':range(3)})

df4

pd.merge(df3,df4,left_on='key1',right_on='key2')

%多对多

df1=pd.DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})

df1

df2=pd.DataFrame({'key':['d','b','a','b','a'],'data2':range(5)})

df2

pd.merge(df1,df2,on='key',how='left')

%根据多个键合并

left=pd.DataFrame({'key1':['foo','foo','bar'],

'key2':['one','two','one'],

'lval':[1,2,3]})

left

right=pd.DataFrame({'key1':['foo','foo','bar','bar'],

'key2':['one','one','one','two'],

'rval':[4,5,6,7]})

right

pd.merge(left,right,on=['key1','key2'],how='outer')

pd.merge(left,right,on='key1')

pd.merge(left,right,on='key1',suffixes=('_left','_right'))

2.索引上的合并

#dataframe的连接键在索引中

%一般索引

left1=pd.DataFrame({'key':['a','b','a','a','b','c'],'value':range(6)})

left1

right1=pd.DataFrame({'group_val':[3.5,7]},index=['a','b'])

right1

pd.merge(left1,right1,left_on='key',right_index=True)

pd.merge(left1,right1,left_on='key',right_index=True,how='outer')

left1.join(right1,on='key')#与上一步等价

%层次化索引

*单方索引

import numpy as np

import pandas as pd

left1=pd.DataFrame({'key1':['ohio','ohio','ohio','neva','neva'],

'key2':[2000,2001,2002,2001,2002],

'data':np.arange(5.)})

left1

right1=pd.DataFrame(np.arange(12).reshape((6,2)),

index=[['neva','neva','ohio','ohio','ohio','ohio'],

[2001,2000,2000,2000,2001,2002]],

columns=['event1','event2'])

right1

pd.merge(left1,right1,left_on=['key1','key2'],right_index=True)

pd.merge(left1,right1,left_on=['key1','key2'],right_index=True,how='outer')

*双方索引

left2=pd.DataFrame([[1,2],[3,4],[5,6]],index=['a','c','e'],columns=['o','n'])

left2

right2=pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],index=['b','c','d','e'],columns=['m','a'])

right2

pd.merge(left2,right2,how='outer',left_index=True,right_index=True)

left2.join(right2,how='outer')

*三方索引

another=pd.DataFrame([[7,8],[9,10],[11,12],[16,17]],index=['a','c','e','f'],columns=['n','or'])

another

left2.join([right2,another])#报错。。不知道为什么报错

left2.join([right2,another],how='outer')#报错。。不知道为什么报错

3.轴向连接

%numpy数组

import numpy as np

arr=np.arange(12).reshape((3,4))

arr

np.concatenate([arr,arr],axis=1)

%Series

s1=pd.Series([0,1],index=['a','b'])

s2=pd.Series([2,3,4],index=['c','d','e'])

s3=pd.Series([5,6],index=['f','g'])

pd.concat([s1,s2,s3])

pd.concat([s1,s2,s3],axis=1)

s4=pd.concat([s1*5,s3])

pd.concat([s1,s4],axis=1)

pd.concat([s1,s4],axis=1,join='inner')

pd.concat([s1,s4],axis=1,join_axes=[['a','c','b','e']])

#层次化索引

result=pd.concat([s1,s2,s3],keys=['one','two','three'])

result

result.unstack()#将层次化索引中的二级索引并入列中

%DataFrame

df1=pd.DataFrame(np.arange(6).reshape(3,2),index=['a','b','c'],columns=['one','two'])

df1

df2=pd.DataFrame(np.arange(4).reshape(2,2),index=['a','c'],columns=['three','four'])

df2

pd.concat({'level1':df1,'level2':df2},axis=1)

df1

df2

pd.concat([df1,df2],ignore_index=True)

4.合并重叠数据

%Series

a=pd.Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],index=['f','e','d','c','b','a'])

a

b=pd.Series(np.arange(len(a)),index=['f','e','d','c','b','a'])

b

b[-1]#倒数第一个数

np.where(pd.isnull(a),b,a)#相当于excel中if用法

b[:-2].combine_first(a[2:])

%DataFrame

df1=pd.DataFrame({'a':[1,np.nan,5,np.nan],'b':[np.nan,2,np.nan,6],'c':range(2,18,4)})

df1

df2=pd.DataFrame({'a':[5,4,np.nan,3,7],'b':[np.nan,3,4,6,8]})

df2

df1.combine_first(df2)#如果有重复,以df1中数值为准

#qcut按照样本分位数对数据进行面元分割

cats=pd.qcut(data,4)#按四分位数进行切割

pd.value_counts(cats)

pd.qcut(data,[0,0.1,0.5,0.9,1])

6.检测和过滤异常值

data.describe()

#选出某列中绝对值超过3的值

col=data[3]

col[np.abs(col)>3]

#选出所有4列中绝对值超过3的行

data[(np.abs(data)>3).any(1)]

#将值限制在区间-3到3以内

data[np.abs(data)>3]=np.sign(data)*3#np.sign返回的是一个由1和-1组成的数值,表示原始值的符号

df=pd.DataFrame(np.arange(5*4).reshape(5,4))

df.take(sampler)

8.计算指标/哑变量

将分类变量转换为哑变量矩阵、指标矩阵。

如果dataframe的某一列中含有K个不同的值,则可以派生出一个K列矩阵或dataframe(其值全为1或0)

import pandas as pd

df=pd.DataFrame({'key':['b','b','a','c','a','b'],'data1':range(6)})

df

pd.get_dummies(df['key'])

#给列名加个前缀prefix

dummies=pd.get_dummies(df['key'],prefix='key')

dummies

df_with_dummy=df[['data1']].join(dummies)

df_with_dummy

#ml-1m数据集

mnames=['movie_id','title','genres']

movies=pd.read_table('movies.dat',sep='::',header=None,names=mnames)

movies[:10]

genre_iter=(set(x.split('')) for x in movies.genres)

genre_iter

genres=sorted(set.union(*genre_iter))

genres

dummies=pd.DataFrame(np.zeros((len(movies),len(genres))),columns=genres)

dummies[:1]

#迭代每一步电影,并将dummies每一行设置为1

for i,gen in enumerate(movies.genres):

dummies.ix[i,gen.split('')]=1

#再将其和movies合并起来

movies_windic=movies.join(dummies.add_prefix('genre_'))

movies_windic

movies_windic.ix[0]

#一个对统计应用有用的秘诀是:结合get_dummies和诸如cut之类的离散化函数

values

bins=[0,0.2,0.4,0.6,0.8,1]

pd.get_dummies(pd.cut(values,bins))

9.字符串操作

%字符串对象方法

val='a,b, guido'

val.split(',')

pieces=[x.strip() for x in val.split(',')]#strip去掉空格、换行符等

pieces

'::'.join(pieces)

#子串定位

'guido' in val

val.index(',')#用来判断分隔符在不在变量中,在则为1,不在则为报错

val.find(':')#用来判断分隔符在不在变量中,在则为1,不在则为-1

val.count(',')#分隔符计数

val.replace(',','::')

10.正则表达式regex

re 模块的函数可以分为三个大类:模式匹配、替换、拆分

#假设我要拆分一个字符串,分隔符为数量不定的一组空白符。描述一个或多个的空白符的regex是\s+

import re

text="foo bar\t baz \tqux"

re.split('\s+',text)

regex=re.compile('\s+')#设置正则表达式

regex.split(text)

regex.findall(text)#得到匹配regex的所有模式

regex.match(" ")#验证引号中的值与正则表达式匹不匹配,若不匹配则不返回任何值

此处 是匹配的。

%pandas中矢量化的字符串函数

data=pd.Series(data)

data

data.isnull

#检查各个邮箱是否含有gmail

一起学习的小伙伴如果有什么想法或者意见,欢迎沟通~

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180211G0SSV700?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券