本文是对《利用python 进行数据分析》中关于“数据规整化:清理转化合并和重塑”的回顾性总结笔记,并附上自己的相关代码与注释。
目录
数据合并
pd.merge
pd.concat 此为重点
pd.conbine_first
重塑和轴向转换
stack与unstack
pivot
数据转换-替换映射重命名与离散化
重复值与去重 duplicated和drop_duplicates
替换
映射map
重命名轴索引 rename
离散化和面元划分pd.cut和pd.qcut
字符串操作
字符串操作的矢量化与正则表达式嵌入
pd自带字符串函数方法汇总
基本正则表达式
含义
merge函数可以根据一个或多个键将不同DataFrame中的行连接起来,本质上实现的是类似数据库中的join连接操作。merge函数默认是做inner join ,取交集。
参数
主要参数包括:left,right,how,on,left_on,right_on,left_index,right_index,sort等
具体参数含义
实例
df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})
df2 = DataFrame({'key': ['a', 'b', 'd'], 'data2': range(3)})
pd.merge(df1, df2, on='key') # 默认情况下,多对一,merge做的是inner 连接,结果中的键是交集。当指定how=outer,即外连接时才取的是键的并集,组合了左连接和右连接的效果。
输出: 注意上方 :# 默认情况下,多对一,merge做的是inner 连接,结果中的键是交集。当指定how=outer,即外连接时才取的是键的并集,组合了左连接和右连接的效果
data1 key data2
0 0 b 1
1 1 b 1
2 6 b 1
3 2 a 0
4 4 a 0
5 5 a 0
df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],'data1': range(7)})
df4 = DataFrame({'rkey': ['a', 'b', 'd'], 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey') #left_on 指定左边连接的键。right_on 指定右边连接的键
输出 : # 注意#left_on 指定左边连接的键。right_on 指定右边连接的键
data1 lkey data2 rkey
0 0 b 1 b
1 1 b 1 b
2 6 b 1 b
3 2 a 0 a
4 4 a 0 a
5 5 a 0 a
print(pd.merge(df1, df2, how='outer')) # 外连接,取的是键的并集,多对多连接产生的是行的笛卡尔积。
输出 :# 外连接,取的是键的并集,多对多连接产生的是行的笛卡尔积。
data1 key data2
0 0.0 b 1.0
1 1.0 b 1.0
2 6.0 b 1.0
3 2.0 a 0.0
4 4.0 a 0.0
5 5.0 a 0.0
6 3.0 c NaN
7 NaN d 2.0
left1 = DataFrame({'key': ['a', 'b', 'a', 'c','a', 'b'],
'value': range(6)})
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
s=pd.merge(left1,right1,left_on='key',right_index=True) # 左侧DataFrame以指定列用作连接键,右侧以索引用作连接键。默认还是inner,结果的索引以key的排序后,出现在左侧中的索引为默认索引
print(s.index)
print(s)
# 注意 : 一侧列一侧索引的连接 。上方,左侧DataFrame以指定列用作连接键,右侧以索引用作连接键。默认还是inner,结果的索引以key的排序后,出现在左侧中的索引为默认索引
输出:
nt64Index([0, 2, 4, 1, 5], dtype='int64')
key value group_val
0 a 0 3.5
2 a 2 3.5
4 a 4 3.5
1 b 1 7.0
5 b 5 7.0
关于层次化索引 的合并 的实例:
lefth = DataFrame({'key1': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'key2': [2000, 2001, 2002, 2001, 2002], 'data': np.arange(5.)})
righth = DataFrame(np.arange(12).reshape((6, 2)), index=[['Nevada', 'Nevada', 'Ohio', 'Ohio', 'Ohio', 'Ohio'],[2001, 2000, 2000, 2000, 2001, 2002]], # 层次化的索引
columns=['event1', 'event2'])
s=pd.merge(lefth,righth,left_on=['key1','key2'],right_index=True) #注意因为右侧是二级层次化索引,所以左侧注意有两个列
print(s)
print(s.index) #这个表明index也有可能出现重复值
输出
data key1 key2 event1 event2
0 0.0 Ohio 2000 4 5
0 0.0 Ohio 2000 6 7
1 1.0 Ohio 2001 8 9
2 2.0 Ohio 2002 10 11
3 3.0 Nevada 2001 0 1
Int64Index([0, 0, 1, 2, 3], dtype='int64')
实例:
left1 = DataFrame({'key': ['a', 'b', 'a', 'c','a', 'b'],
'value': range(6)})
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
right1.loc['e']=20
print(right1) #有e
print(type(right1))
left1.join(right1,on='key')# 注意join 可以用于合并多个带有相同或相似索引的DataFrame对象,而不管他们之间是否有成蝶的列
# 注意 : 由于历史原因,对于默认的内连接,DataFrame的join方法在连接键上是做左连接!!! 结果中右边dataframe中后的 e 这行数据没有出现在数据中
输出
group_val
a 3.5
b 7.0
e 20.0
key value group_val
0 a 0 3.5
1 b 1 7.0
2 a 2 3.5
3 c 3 NaN
4 a 4 3.5
5 b 5 7.0
pandas.concat
含义
可以使得数据沿着一条轴将多个对象堆叠到一起。轴向连接 concat 又被称为 连接,绑定、或者堆叠。操作对象既可以为series又可以为dataframe。
参数
重点-实例 # 轴向连接 concat 又被称为 连接,绑定、或者堆叠。默认是axis=0,行数变,即增加了行了
s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
pd.concat([s1,s2,s3]) # 轴向连接 concat 又被称为 连接,绑定、或者堆叠。默认是axis=0,行数变,即增加了行了
输出
a 0
b 1
c 2
d 3
e 4
f 5
g 6
dtype: int64
实例: keys参数,与连接对象有关的值,用于形成连接轴向上的层次化索引。可以是任意值的列表或数组、元组数组、数组列表(如果将levels设置成多级数组的话);
s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
result=pd.concat([s1,s2,s3],keys=['one','two','three']) # keys参数,与连接对象有关的值,用于形成连接轴向上的层次化索引。可以是任意值的列表或数组、元组数组、数组列表(如果将levels设置成多级数组的话)
print(result)
print(type(result)) #默认concat是沿着axis=0进行合并,对于Sereis得到的仍然是Series。
print(result.index)
print("****")
result.unstack() # 将层次化索引的Series 通过unstack函数转化为 DataFrame 。 unstack将数据的行旋转为列 。 stack 将数据的列旋转为行
输出
one a 0
b 1
two c 2
d 3
e 4
three f 5
g 6
dtype: int64
MultiIndex(levels=[[u'one', u'two', u'three'], [u'a', u'b', u'c', u'd', u'e', u'f', u'g']],
labels=[[0, 0, 1, 1, 1, 2, 2], [0, 1, 2, 3, 4, 5, 6]])
******
a b c d e f g
one 0.0 1.0 NaN NaN NaN NaN NaN
two NaN NaN 2.0 3.0 4.0 NaN NaN
three NaN NaN NaN NaN NaN 5.0 6.0
series的concat
s=pd.concat([s1,s2,s3],axis=1,keys=['one','two','three'])# 将多个Series 沿着axis=1 ,concat到一起后就变成了DataFrame,keys为指定生成DataFrame的columns表头列名。(默认concat是沿着axis=0进行合并,对于Sereis得到的仍然是Series。)
print(type(s))
print(s.columns)
print(s)
输出
Index([u'one', u'two', u'three'], dtype='object')
one two three
a 0.0 NaN NaN
b 1.0 NaN NaN
c NaN 2.0 NaN
d NaN 3.0 NaN
e NaN 4.0 NaN
f NaN NaN 5.0
g NaN NaN 6.0
df1 = DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],columns=['one', 'two'])
df2 = DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
columns=['three', 'four'])
s=pd.concat([df1, df2], axis=1, keys=['level1', 'level2']) #对于数个DataFrame沿着axis=1合并,keys 也会是表头列(列中的最上级)
print(s)
print(s.columns) # 注意: 列也有层次化的
输出
level1 level2
one two three four
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0
MultiIndex(levels=[[u'level1', u'level2'], [u'four', u'one', u'three', u'two']],
labels=[[0, 0, 1, 1], [1, 3, 2, 0]])
# 如果传入的不是列表而是一个字典,则字典的key会被当做keys选项的值
pd.concat({'level1':df1,'level2':df2},axis=1)
输出
level1 level2
data1 key data2 key
0 0 b 0.0 a
1 1 b 1.0 b
2 2 a 2.0 d
3 3 c NaN NaN
4 4 a NaN NaN
5 5 a NaN NaN
6 6 b NaN NaN
print(pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],
names=['upper', 'lower'])) #对于names参数,如果设置了keys或者names,则names表示 用于创建分层级别的名称。比如此 两个用于管理层次化索引的参数,
输出
upper level1 level2
lower data1 key data2 key
0 0 b 0.0 a
1 1 b 1.0 b
2 2 a 2.0 d
3 3 c NaN NaN
4 4 a NaN NaN
5 5 a NaN NaN
6 6 b NaN NaN
conbine_first
含义
可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。主要是用于有缺失值的场景,实现if-else的矢量化对齐。
例子
a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, 30],
index=['f', 'e', 'd', 'c', 'b', 'a'])
b = Series(np.arange(len(a), dtype=np.float64),
index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
b.combine_first(a) # 以b为基础,得到如果b中对应a中的index处的值缺失则用a中对应位置的值进行填充过的序列。
上面:以b为基础,得到如果b中对应a中的index处的值缺失则用a中对应位置的值进行填充过的序列。
输出
f 0.0
e 1.0
d 2.0
c 3.0
b 4.0
a 30.0
dtype: float64
对于DataFrame combine_first也会在列上做同样的事情。即combine_first可以看成是用参数对象中的数据为调用者对象的缺失数据 ”打补丁“
df1 = DataFrame({'a': [1., np.nan, 5., np.nan],
'b': [np.nan, 2., np.nan, 6.],
'c': range(2, 18, 4)})
df2 = DataFrame({'a': [5., 4., np.nan, 3., 7.],
'b': [np.nan, 3., 4., 6., 8.]})
print(df1.combine_first(df2))
输出
a b c
0 1.0 NaN 2.0
1 4.0 2.0 6.0
2 5.0 4.0 10.0
3 3.0 6.0 14.0
4 7.0 8.0 NaN
unstack含义
对于一个简单的DataFrame,用stack 将数据的列” 旋转“ 为行,会形成层次化索引,即堆叠起来了。 用unstack即将层次化索引分解了,旋转了一层到列中去了,即unstack分解
注意此实例
data=DataFrame(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colorado'],name='state'),columns=pd.Index(['one','two','three'],name='number')) # 层次化索引
print(data)
print(data.index)
print(data.columns)
print("stack")
result=data.stack() # 对于一个简单的DataFrame,用stack 将数据的列” 旋转“ 为行,得到一个可能为层次化索引的Series #注意如果层次化,则原列名在里面
print(result)
print(type(result)) # Series
print("unstack")
print(result.unstack()) # 对于一个层次化索引的Series ,用unstack 将其重排为一个DataFrame 数据的行 旋转为列 。 默认情况下unstack操作的是最内层(stack也是如此),如此为one、two、three,即编号1 ,如此如果不指定则是最内层的number
print(result.unstack(1)) # # 注意默认为1,才可以为原stack的逆运算
print("自己指定外层的编号")
print(result.unstack(0)) # 指定传入分层级别的编号或者名称即可对其他级别进行unstack操作;如此传入编号0,下面传入名称
print('unstack里面也可传入层次化索引的 名称')
print(result.unstack('state')) #unstack里面也可传入层次化索引的 名称
上面注意: 对于一个简单的DataFrame,用stack 将数据的列” 旋转“ 为行,得到一个可能为层次化索引的Series #注意如果层次化,则原列名在里面。对于一个层次化索引的Series ,用unstack 将其重排为一个DataFrame 数据的行 旋转为列 。 默认情况下unstack操作的是最内层(stack也是如此),如此为one、two、three,即编号1 ,如此如果不指定则是最内层的number 。
尤其注意: unstack参数默认1,才可以为原stack的逆运算
输出
number one two three
state
Ohio 0 1 2
Colorado 3 4 5
Index([u'Ohio', u'Colorado'], dtype='object', name=u'state')
Index([u'one', u'two', u'three'], dtype='object', name=u'number')
stack
state number
Ohio one 0
two 1
three 2
Colorado one 3
two 4
three 5
dtype: int64
unstack
number one two three
state
Ohio 0 1 2
Colorado 3 4 5
number one two three
state
Ohio 0 1 2
Colorado 3 4 5
自己指定外层的编号
state Ohio Colorado
number
one 0 3
two 1 4
three 2 5
unstack里面也可传入层次化索引的 名称
state Ohio Colorado
number
one 0 3
two 1 4
three 2 5
pivot
含义
pivot 的作用是用表格中的数据重新划分作为索引和列的数据结构。 其实就是用set_index创建层次化索引,再用unstack重塑:
参数
pivot方法中,前两个参数对应的取值分别对应行索引和列索引的列名。此处第一个参数date对应的各个取值如1959-03-31对应结果的行索引,第二个参数item对应的取值如realgdp 对应结果中的一个列realgdp,最后一个参数值用于填充DataFrame数据列的值。 当我们未设置aggfunc时,它默认aggfunc='mean'计算均值。
实例 :pivot其实就是用set_index创建层次化索引,再用unstack重塑;pivot方法中,前两个参数对应的取值分别对应行索引和列索引的列名。
ldata=data.stack().reset_index().rename(columns={0:'value'})
print("数据:\n{}".format(ldata.head(5)))
unstacked=ldata.set_index(['date','item']).unstack('item')
print("方式1:重塑set_index和unstack:")# 注意unstacked里索引变为了date
print(unstacked[:3])
print(type(unstacked)) # 注意 pivot 其实只是一个快捷方式而已,用set_index 创建层次化索引,再用 unstacked 重塑
# unstacked[:7]
print("方式2 用pivot ")
wdata=ldata.pivot('date','item','value') # pivot方法中,前两个参数对应的取值分别对应行索引和列索引的列名。此处第一个参数date对应的各个取值如1959-03-31对应结果的行索引,第二个参数item对应的取值如realgdp 对应结果中的一个列realgdp,最后一个参数值用于填充DataFrame数据列的值。
print(wdata[:3])
输出
数据:
date item value
0 1959-03-31 realgdp 2710.35
1 1959-03-31 unemp 5.8
2 1959-06-30 realgdp 2778.8
3 1959-06-30 unemp 5.1
4 1959-09-30 realgdp 2775.49
方式1:重塑:
value
item realgdp unemp
date
1959-03-31 2710.35 5.8
1959-06-30 2778.8 5.1
1959-09-30 2775.49 5.3
方式2 用pivot
item realgdp unemp
date
1959-03-31 2710.35 5.8
1959-06-30 2778.8 5.1
1959-09-30 2775.49 5.3
重复值和去除重复值
duplicated()
print(data.duplicated()) # DataFrame的duplicated 方法返回一个布尔型Series,表示各行是否重复。判断的时候,第一次出现的值不会认为是重复的,即判断结果值会为False,后面重复的才会为True
drop_duplicates
print(data.duplicated()) # DataFrame的duplicated 方法返回一个布尔型Series,表示各行是否重复。判断的时候,第一次出现的值不会认为是重复的,即判断结果值会为False,后面重复的才会为True
replace
注意原值并不会改变,得到一个新的对象
实例
data=Series([1.,-999.,2.,-999.,-1000.,3.])
print(data.replace(-999,np.nan)) # 实现值替换,但是原数据本身并不会发生变化。第一个参数为需要替换的对象,第二个参数为替换后的给值。也可以一次性给多个
print(data)
print(data.replace([-999.,2.0],np.nan)) # -999.,2.0 都被替换成NaN 了
print(data.replace([-999,2.0],[np.nan,0])) #传入多个替换值。用列表 -999被替换成NaN ,2.0替换成0
print(data.replace({-999:np.nan,-100:0})) # 传入的参数也可以是字典
输出
0 1.0
1 NaN
2 2.0
3 NaN
4 -1000.0
5 3.0
dtype: float64
0 1.0
1 -999.0
2 2.0
3 -999.0
4 -1000.0
5 3.0
dtype: float64
0 1.0
1 NaN
2 NaN
3 NaN
4 -1000.0
5 3.0
dtype: float64
0 1.0
1 NaN
2 0.0
3 NaN
4 -1000.0
5 3.0
dtype: float64
0 1.0
1 NaN
2 2.0
3 NaN
4 -1000.0
5 3.0
dtype: float64
map 实例
注意: Series的map方法可以接受一个函数 或者 含有映射关系的字典型对象 . 注意 对于字典映射对象相当于进行了按key 给value 值的替换!
data = DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami',
'corned beef', 'Bacon', 'pastrami', 'honey ham',
'nova lox'],'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
data['animal']=data['food'].map(str.lower).map(meat_to_animal) # Series的map方法可以接受一个函数 或者 含有映射关系的字典型对象 . 注意 对于字典映射对象相当于进行了按key 给value 值的替换!
print(data)
输出
food ounces animal
0 bacon 4.0 pig
1 pulled pork 3.0 pig
2 bacon 12.0 pig
3 Pastrami 6.0 cow
4 corned beef 7.5 cow
5 Bacon 8.0 pig
6 pastrami 3.0 cow
7 honey ham 5.0 pig
8 nova lox 6.0 salmon
rename
实例
data = DataFrame(np.arange(12).reshape((3, 4)),
index=['Ohio', 'Colorado', 'New York'],
columns=['one', 'two', 'three', 'four'])
print(data.rename(index=str.title,columns=str.upper) ) # str.title 实现的是标题化的字符串转换,即使得所有单词都是以大写开始而其余字母都为小写 。DataFrame的rename函数 可以实现对其索引和列标签进行修改(虽然默认是不会改原值),如果想实现原值替换,可以通过给参数inplace=True
print(data)
data.rename(index=str.title,columns=str.upper,inplace=True)
print(data)
输出
ONE TWO THREE FOUR
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
ONE TWO THREE FOUR
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
pd.cut
含义:划分为桶
实例 # 注意: # 关于边界的取值,默认是左闭右开,即右侧不闭合,right为False
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins) #bins为面元,即要划分的区间点,边界值。 pandas.cut 返回的是一个特殊的Categorical 对象。可以将其看做一组表示面元名称的字符串。实际上它含有一个为年龄数据进行标号的labels属性
print(cats)
输出
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
pd.cut(ages,[18,26,36,61,100],right=False) # 关于边界的取值,默认是左闭右开,即右侧不闭合,right为False
输出
[[18, 26), [18, 26), [18, 26), [26, 36), [18, 26), ..., [26, 36), [61, 100), [36, 61), [36, 61), [26, 36)]
Length: 12
Categories (4, interval[int64]): [[18, 26) < [26, 36) < [36, 61) < [61, 100)]
# 可以自己设置labels的分组名称
group_names= ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
s=pd.cut(ages,bins,labels=group_names)
print(s)
输出
[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MiddleAged, MiddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]
data=np.random.rand(20)
实例
s=pd.cut(data,4,precision=2) # 此即向cut传入的不是确切的面元边界值bins,而是面元的数量4 ,则会根据数据的最小值和最大值来计算划分为4个等长的面元
print(s)
print(s.value_counts()) #划分的区间间隔等长,但是各个区间的量不一定相同。
输出
[(0.27, 0.51], (0.51, 0.75], (0.75, 0.99], (0.51, 0.75], (0.75, 0.99], ..., (0.51, 0.75], (0.75, 0.99], (0.27, 0.51], (0.75, 0.99], (0.024, 0.27]]
Length: 20
Categories (4, interval[float64]): [(0.024, 0.27] < (0.27, 0.51] < (0.51, 0.75] < (0.75, 0.99]]
(0.024, 0.27] 5
(0.27, 0.51] 3
(0.51, 0.75] 5
(0.75, 0.99] 7
dtype: int64
pandas的字符串操作(矢量化)里面也可以嵌入正则表达式
主要函数包括: str.contains,str.count,match,等
实例: 注意通过 data.map ,所有的字符串和正则表达式方法都能被应用于(传入lambda表达式或其他函数)各个值,但是如果存在NA就会报错。
data={'Dave':'[email protected]','Steve':'[email protected]','Rob':'[email protected]','Wes':np.nan}
data=Series(data)
# 通过 data.map ,所有的字符串和正则表达式方法都能被应用于(传入lambda表达式或其他函数)各个值,但是如果存在NA就会报错。 为了解决这个问题,Series有一些能跳过NA值的字符串操作方法。通过Series的str属性即可访问这些方法,如str.contains可以坚持是否包含某个子串
data.str.contains('gmail')
输出
Dave False
Rob True
Steve True
Wes NaN
dtype: object
# 矢量化使用正则
data={'Dave':'[email protected]','Steve':'[email protected]','Rob':'[email protected]','Wes':np.nan}
data=Series(data)
pattern=r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}' # 提取邮件格式的正则表达式
matches = data.str.match(pattern, flags=re.IGNORECASE)
matches
输出
Dave True
Rob True
Steve True
Wes NaN
dtype: object
常见内置的字符串操作方法
主要函数包括: split,strip,replace,count等
使用方法直接见实例:
val='a,b, guido'
print(val.split(',')) # 字符串的分割,得到一个list
print('guido' in val) # 检测子串 ,用in ,看子串是否在目标中,如果在返回True,如果不在返回false
print(val.index(',')) # val.index 如果在字符串中找到子串,则返回子串第一个字符所在的位置。如果没有找到,则引发valueError
print(val.find(',')) # 如果在字符串中找到子串,则返回第一个发现的子串的第一个字符所在的位置(同index);但是如果没有找到,则返回-1 ,对于index如果没有找到则引发的为valueError
输出
['a', 'b', ' guido']
True
1
1
注意自带的内置 函数列表
基本正则表达式(先只了解)
常见正则表达式主要包括:re.split,re.match等
re.split
实例
# re.split
import re
# Python 内置的re模块负责对字符串应用正则表达式. re模块的函数可以分为三大类: 模式匹配,替换以及拆分;
text='foo bar\t baz \tqux'
re.split('\s+',text) # 描述一个或多个空白符的regex 是\s+
输出
['foo', 'bar', 'baz', 'qux']
regex=re.compile('\s+')
regex.split(text) # 效果同上面。调用re.split('\s+',text)时,正则表达式会先被编译,然后再在text上调用其split方法。也可以用这里的先用re.compile将正则表达式先编译regex,以得到一个可重用的regex对象
输出
同上
re.findall
实例
print(regex.findall(text))# 如果只是希望得到匹配的regex的所有模式,则可以使用findall方法。如下得到\s++匹配的模式一个或多个空白符
text = """Dave [email protected]
Steve [email protected]
Rob [email protected]
Ryan [email protected]
"""
pattern=r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}' # 提取邮件格式的正则表达式
regex=re.compile(pattern,flags=re.IGNORECASE)
# re.IGNORECASE的作用是使的正则表达式对大小写不敏感
regex.findall(text)
输出
[' ', '\t ', ' \t']
['[email protected]', '[email protected]', '[email protected]', '[email protected]']
match
实例
# 如果 不仅想要找出电子邮件地址,还想将各个地址分成3个部分: 用户名,域名以及域后缀。 要实现此功能,只需将待分段的模式的各部分用圆括号包起来即可。用这种正则表达式所产生的匹配对象,可以通过其groups方法返回一个由模式各段组成的元组
pattern=r'([A-Z0-9._%+-]+)@([A-Z0-9._]+)\.([A-Z]{2,4})'
regex=re.compile(pattern,flags=re.IGNORECASE)
m = regex.match('[email protected]')
print(m.groups())# groups方法返回一个由模式各段组成的元组
输出
('wesm', 'bright', 'net')
主要方法汇总小结(了解)
附录:思维导图概览图
参考与鸣谢:
《python进行数据分析》