pandas数据规整化:清理,转换,合并,重塑

pandas数据规整化:清理,转换,合并,重塑

  • 合并数据集
    • pandas.merge
    • pandas.concat
    • pandas.combine_first
  • 重塑和轴转向
    • 旋转stack和unstack
    • pivot
  • 数据转换
    • 移除重复数据
    • 函数或映射处理数据
    • 替换值
    • 重命名轴索引
    • 离散化和面元划分
    • 检查和过滤异常值
    • 排列和随机采样
    • 哑变量
  • 字符串操作
    • python内置字符串方法
    • 正则表达式
    • pandas中矢量化字符串函数

合并数据集

pandas.merge

pd.merge(df1,df2,on=['key1','key2']) #两个key组成为一个独立体

pd.merge(df1,df2,left_on='lkey',right_on='rkey')
pd.merge(df1,df2,left_on='lkey',right_index=True) #索引上的合并
pd.merge(df1,df2,left_on=['key1','key2'],right_index=True) #复合索引必须知道两个key
pd.merge(df1,df2,left_index=True,right_index=True) #合并双方索引
df2.join(df1,how='outer') #合并双方索引

pd.merge(df1,df2,on='key',how='outer') #多对多产生笛卡尔积行

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

json

df1.join(df2,on='key') #join.默认左连接

df1.join([df1,df2],how='outer') #链接多个

merge函数的参数

参数 说明
left 左侧df
right 右侧df
how 默认inner,还有outer,left,right
on 用于链接的列名或列名列表,若未指定以交集作为链接键
left_on 指定左侧作为链接键的列名或列名列表
right_on 指定右侧作为链接键的列名或列名列表
left_index 是否使用左侧index作为链接键
right_index 是否使用右侧index作为链接键
sort 根据链接键对数据排序,默认为True
suffixes 传入字符串值元组,分别有左右则键后缀
copy 默认为True

pandas.concat

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

pd.comcat([s1,s2,s3],axis=1,join='inner') #默认为outer

pd.comcat([s1,s2,s3],axis=1,join_axes=[list('acbe')]) #指定轴上使用的索引

result=pd.comcat([s1,s2,s3],keys='one,two,three'.split(',')) #创建层次化索引
result=pd.comcat({
     'one':df1,'two':df2,'three':df3},names=['upper','lower']) #字典键作为keys值 names指定索引名字
result.unstack() #内层行索被设为列索

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

concat函数的参数

参数 说明
objs 参与链接的pandas对象的列表或字典
axis
join 链接方式,默认outer,还有inner
join_axes 志明用于其他n-1条轴的索引,不执行并集或交集运算
keys 设置层次化索引
levels 指定用作层次化索引各级别上的索引,如果设置了keys
names 用于层次化索引的名称
verify_integrity 检查结果对象新轴上的重复情况,发现则引发异常,默认Flase允许重复
ignore_index 不保留链接轴上的索引,产生新索引range(total_length)

pandas.combine_first

np.where(pd.isnull(df1),df2,df1)
df1.combine_first(df2

重塑和轴转向

旋转stack和unstack

stack:将 列 旋转为 行
unstack:将 行 旋转为 列

df.unstack() #默认操作最内层
df.unstack(0) #操作最外层
df.unstack('state') #指定索引级别操作
df.unstack().stack(dropna=False) #默认为True
df.unstack('state').stack('side') 

pivot

pivoted=df.pivot('data','item','value')

df.['value2']=np.random.randn(len(df))
pivoted=df.pivot('data','item') #外层索引为[value,value2]

unstacked=df.set_index(['date','item']).unstack('item') #pivoted==unstacked

数据转换

移除重复数据

df.duplicated() #返回bool型Series,表示各行是或否为重复行
df.drop_duplicates() #删除重复行 默认判断全部列

df.drop_duplicates(['k1']) #指定部分列进行重复项判断
df.drop_duplicates(['k1','k2'],take_last=True) #设置保留最后值组合,默认保留第一出现值组合

函数或映射处理数据

meat_to_animal={
     }
data['animal']=data['food'].map(str.lower).map(meap_to_animal)
data['animal']=data['food'].map(lambda x:meap_to_animal[x.lower()])

替换值

df.replace(sv,rv)
df.replace([sv1,sv2],[rv1,rv2])
df.replace({
     sv1:rv1,sv2:rv2

重命名轴索引

data.index.map(str.upper)
data.rename(index=str.title,columns=str.upper)
data.rename(index={
     'OHIO':'INDIANA'},columns={
     'three':'peekaboo'},inplace=True)

离散化和面元划分

ages=[20,22,25,27,21,23,27,31,61,45,41,32]
bins=[18,25,35,60,100]
cats=pd.cut(ages,bins,right=True,labels=list('abcd')) #返回Categorical类型
cats.codes #返回所属区间的标号,始于0
cats.categories #返回所有区间
pd.value_counts(cats)

cats=pd.cut(ages,4,precision=2)  #最大值减最小值除4为分位,最大值为最大值,precision设置小数位数

cats=pd.qcut(ages,4,precision=2) #按4分位进行切割,4分数量接近相等

cats=pd.qcut(ages,[0,0.1,0.5,0.9,1],precision=2) #自定义分位数

检查和过滤异常值

np.random.seed(12345)
data=pd.DataFrame(np.random.randn(1000,4))
data[3][np.abs(data[3])>3] #找出绝对值大于3的值
data[(np.abs(data)>3).any(1)] #找出整行有包含绝对值大于3的值
data[np.abs(data)>3]=np.sign(data)*3 #sign返回-1,0,1组成的数组
data.describe()

排列和随机采样

sampler=np.random.permutation(10)
df.take(sampler) #指定行索排序
df.take(np.random.permutation(len(df))[:3]) #随机抽取3行数据
np.random.randint(0,10,size=100) #随机生成整数区间0-10,100个

哑变量

调用

df=pd.DataFrame({
     'key':list('bbacab'),'data':[2,2,3,4,5,6]})
df.index='one,two,three,four,five,six'.split(',')
dummies=pd.get_dummies(df['key'],prefix='key') #把列数据唯一值设置为列,并加入前缀
df[['data']].join(dummies) #df[['data']]返回时DataFrame

原理

movies=pd.read_table()
genre_iter=(set(x.split('|')) for x in movies.genres)
genres=sorted(set.union(*genre_iter)) #相当于传入v1,v2,...
dummies=pd.DataFrame(np.zeros((len(movies),len(genres))),columns=genres)
for idx,gen in enumerate(movies.genres):
  dummies.ix[idx,gen.split('|')]=1
movies.join(dummies.add_prefix('Genre_'))

结合cut之类的离散化函数

values=np.random.rand(10)
bins=[0,0.2,0.4,0.6,0.8,1.]
pd.get_dummies(pd.cut(values,bins))

字符串操作

python内置字符串方法

方法 说明
count 传入子串,返回其再字符串中出现的次数
startswith,endswith 判断是否以传入子串开头或结尾,返回bool
join 传入序列,用字符串串连返回新字符串
index 返回传入子串首字符位置,没有引发ValueError
find 返回传入子串首字符位置,没有返回-1
rfind 返回最后一个发现的子串的首字符位置
replace 替换指定字符串,后换前
strip,rstrip,lstrip 去除空白符,包括换行和制表
lower,upper,title 大小写及单词首字母大写
ljust,rjust 传入最低宽度,字符串设置左右对齐,缺失以空格填充

正则表达式

基本用法

import re

re.split('\s+',text) #优先自动编译regex
regex=re.compile('\s+') #手动编译
regex.split(text)

pattern=r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
regex=re.compile(pattern,flags=re.IGNORECASE) #对大小写不敏感
regex.findall(text) #返回全部的电子邮件地址列表

m=regex.search(text) #返回第一个匹配项对象
text[m.start():m.end()] #第一个电子邮件

regex.sub('REDACTED',text) #把所有匹配项修改为指定字符串
pattern=r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex=re.compile(pattern,flags=re.IGNORECASE) #对大小写不敏感

m=regex.match(text)
m.group() #返回元组,按括号分成3份

regex.findall(text) #返回列表,表示分成3份的所有元组

regex.sub(r'Username: \1,Domain: \2,Suffix: \3',text) #通过\1\2访问分组


pattern=r'''
(?P[A-Z0-9._%+-]+)@(?P[A-Z0-9.-]+)\.(?P[A-Z]{2,4})'''
regex=re.compile(pattern,flags=re.IGNORECASE) #对大小写不敏感
m=regex.match('text')
m.groupdict #返回字典形式

正则表达式方法

方法 说明
findall,finditer 返回所有非重叠匹配模式的列表,或通过迭代器逐个返回
match 从起始位置开始匹配,匹配成功返回匹配项对象
search 返回第一个匹配项对象
split 根据找到的模式拆分字符串
sub,subn 把所有匹配模式或前n个匹配模式替换指定字符串,可以使用如\1\2表示各分组项

pandas中矢量化字符串函数

方法 说明
cat 元素级字符串链接,可指定分隔符
contains 返回表示是否包含子串或模式的布尔型数组
count 元素级模式出现的次数
endswith,startswith 元素级首位判读
get 获取各元素的第i位字符
join 元素级执行join,针对元素为序列时使用
len 计算各字符串的长度
lower,upper,title 元素级大小写及首字母大写
match 指定模式对各元素执行re.match
findall 返回个字符串的模式列表,指定模式对各元素执行re.findall
pad 设置宽度对齐,添加空白
center 相当于pad(side=‘both’)
repeat 元素级复制加长字符串
replace 用指定字符串替换找到的模式
slice 元素级子串截取
split 根据字符串或正则表达式对字符串拆分
strip,rstrip,lstrip 去除空白符

你可能感兴趣的:(python_数据分析)