python正则表达式
pandas的str方法
对于字符型文本数据,利用pandas库下的str方法可进行基本的数据处理分析。pandas特定的列经过str之后,就可以使用各种python常用的字符处理方法了。
几种常见的str方法如下:
contains()
筛选出含有特定字符串的行:
import pandas as pd
d={'gene':{'a':'gene1','b':'gene2','c':'gene3','d':'gene4'},'expression':{'a':'low:0','b':'mid:3','c':'mid:4','d':'high:9'},'description':{'a':'transposon element','b':'nuclear genes','c':'retrotransposon','d':'unknown'}}
df=pd.DataFrame(d)
print(df)
gene expression description
a gene1 low:0 transposon element
b gene2 mid:3 nuclear genes
c gene3 mid:4 retrotransposon
d gene4 high:9 unknown
df1=df[df['description'].str.contains('transposon')]
print(df1)
gene expression description
a gene1 low:0 transposon element
c gene3 mid:4 retrotransposon
split()
字符串分割(将特定列拿出来,按特定字符分开,然后形成一个新的dataframe)
df1=df['expression'].str.split(':',expand=True)
#expand设置为True
print(df1)
0 1
a low 0
b mid 3
c mid 4
d high 9
expand=True不加的话,df1中将只有一列,其实就是一个series。
当然,可以直接将这两列加到df中:
#df[['exp1','exp2']]直接将新的两列加入原先dataframe中
df[['exp1','exp2']]=df['expression'].str.split(':',expand=True)
print(df)
gene expression description exp1 exp2
a gene1 low:0 transposon element low 0
b gene2 mid:3 nuclear genes mid 3
c gene3 mid:4 retrotransposon mid 4
d gene4 high:9 unknown high 9
另一个例子
df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm',
'Budapest_PaRis', 'Brussels_londOn'],
'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )',
'12. Air France', '"Swiss Air"']})
df
From_To FlightNumber RecentDelays Airline
0 LoNDon_paris 10045.0 [23, 47] KLM(!)
1 MAdrid_miLAN NaN [] <Air France> (12)
2 londON_StockhOlm 10065.0 [24, 43, 87] (British Airways. )
3 Budapest_PaRis NaN [13] 12. Air France
4 Brussels_londOn 10085.0 [67, 32] "Swiss Air"
将From_To列从_分开,分成From, To两列,并删除原始列
另一种方法将两列加到原先df中去
temp = df.From_To.str.split('_', expand=True)
temp.columns = ['From', 'To']
df = df.join(temp)
df = df.drop('From_To', axis=1)
df
FlightNumber RecentDelays Airline From To
0 10045 [23, 47] KLM(!) LoNDon paris
1 10055 [] <Air France> (12) MAdrid miLAN
2 10065 [24, 43, 87] (British Airways. ) londON StockhOlm
3 10075 [13] 12. Air France Budapest PaRis
4 10085 [67, 32] "Swiss Air" Brussels londOn
replace()
字符串的替换
df['gene']=df['gene'].str.replace('gene','Gene')
print(df)
gene expression description exp1 exp2
a Gene1 low:0 transposon element low 0
b Gene2 mid:3 nuclear genes mid 3
c Gene3 mid:4 retrotransposon mid 4
d Gene4 high:9 unknown high 9
strip()包括lstrip和rstrip
去除特定字符strip(包括lstrip和rstrip)
df1['expression']=df1['expression'].str.lstrip('mid:')
#delete “mid:”
更多方法原文链接:https://blog.csdn.net/qq_28219759/article/details/52919233
extract 正则提取数据 正则表达式
pandas.Series.str.extract
Series.str.extract(self,pat,flags = 0,expand = True )
抽取匹配的字符串出来,注意要加上括号,把你需要抽取的东西标注上
正则表达式
pat:patterns模式
基本模式
以下称为匹配字符最常用的几种模式:
1. a,X,9,<-普通字符,单独的匹配字符本身;
2. .(点号)-匹配除'\ n'的任意字符
3. \ w-(小写w)匹配任意的'word'型的字符:字母或者数字或下划线[a-zA-Z0- 9_];对齐的是'word'型只匹配别名而不是一个单词的'word'; \ W(大写W )匹配任意的'non-word'非word的字符
4. \ b-单词和非单词之间的边界(word型和non-wordtype的分界)
5. \ s-(小写s)匹配替换空白字符-空格,换行,返回,tab形式为[ \n\r\t\f]。
\ S(大写S)匹配任意的非空白字符的字符
6. \ t,\ n,\ r-制表符,换行符,返回
7. \ d-十进制的数字[0-9]
8. ^ =开始,$ =结束-分别匹配字符开始和结束位置
9. \-对字符进行转义。例如说,用。匹配。或者用\匹配\;如果您不确定一个字符是否有特殊含义,例如说'@',您可以在其前面加上反斜杠,'\ @',来保证把它当做一个字符来对待
搜索是从字符串开始到结尾的,在第一个匹配到的地方停止,且所有的模式必须完全匹配。
"""示例"""
match = re.search(r'iii', 'piiig') => found, match.group() == "iii"
match = re.search(r'igs', 'piiig') => not found, match == None
## . = any char but \n
match = re.search(r'..g', 'piiig') => found, match.group() == "iig"
## \d = digit char, \w = word char
match = re.search(r'\d\d\d', 'p123g') => found, match.group() == "123"
match = re.search(r'\w\w\w', '@@abcd!!') => found, match.group() == "abc"
重复
1.+ 在样式的左边出现1次或多次(至少出现一次),例如’i +’=一个或多个i
2.* 在样式的左边出现0次或多次(只要出现一次)
3.\? 在样式的左边出现0次或1次(至多出现一次)
最左侧开始和最大匹配
re.search(r'pi+', 'piiig') => found, match.group() == "piii"
re.search(r'i+', 'piigiiii') => found, match.group() == "ii"
re.search(r'\d\s*\d\s*\d', 'xx1 2 3xx') => found,match.group() == "1 2 3"
re.search(r'\d\s*\d\s*\d', 'xx12 3xx') => found, match.group() == "12 3"
re.search(r'\d\s*\d\s*\d', 'xx123xx') => found, match.group() == "123"
re.search(r'^b\w+', 'foobar') => not found, match == None
re.search(r'b\w+', 'foobar') => found, match.group() == "bar"
方括号
- 方括号可以用来表示字符的集合,而[abc]匹配“ a”或“ b”或“ c”
- r’[\w.-]+@[\w.-]+'来匹配整个邮箱地址---->类似alice-b@google.com
- 可以利用一个短横线来表明范围,例如[a-z]匹配所有的小写字符
- 如果不想让短横线表示范围,可以把它放到最后来避免这个问题,例如[abc-]。
- 在方括号表达式中的最前面加上表示取反,例如[ ab]表示匹配任何不为’a’或’b’的字符。
组提取
正则表达式中的“ group”允许您选出文本中匹配到的部分。假设在邮箱地址问题中我们是想分别提取用户名和主机名,为了解决这个问题,在用户名和主机名上的匹配模式上加上(),如:r’([\w.-]+)@([\w.-]+)'可以解决这个问题。在这种情况下,括号不会改变匹配模式的规则,而是在匹配文本内部建立一个逻辑的“组”。对于一次成功的匹配, group(1)表示的是匹配文本中对应第1个小括号的匹配内容,match.group(2)则示的是匹配文本中对应第2个小括号的匹配内容。但是match.group()表示的仍然是整个匹配到的文本。
str = 'purple alice-b@google.com monkey dishwasher'
match = re.search('([\w.-]+)@([\w.-]+)', str)
if match:
print match.group() ## 'alice-b@google.com' (the whole match)
print match.group(1) ## 'alice-b' (the username, group 1)
print match.group(2) ## 'google.com' (the host, group 2)
找到所有findall()
findall()可能是re模块中最简单而又强大的函数了。上面我们所使用的re.search()只能够找到第一个符合匹配模式的文本。findall()可以找到所有的能够匹配上的文本并以列表的形式返回,列表中的每一个元素表示一个匹配。
str = 'purple alice@google.com, blah monkey bob@abc.com blah dishwasher'
emails = re.findall(r'[\w\.-]+@[\w\.-]+', str) ## ['alice@google.com', 'bob@abc.com']
带文件的findall
# Open file
f = open('test.txt', 'r')
# Feed the file text into findall(); it returns a list of all the found strings
strings = re.findall(r'some pattern', f.read())
findall和组
括号表达式()和findall()可以结合起来。如果匹配模式包含两个或两个以上的括号组,那么findall()将不再以列表(list)形式返回,而是以元组(tuple)形式返回。
str = 'purple alice@google.com, blah monkey bob@abc.com blah dishwasher'
tuples = re.findall(r'([\w\.-]+)@([\w\.-]+)', str)
print tuples ## [('alice', 'google.com'), ('bob', 'abc.com')]
for tuple in tuples:
print tuple[0] ## username
print tuple[1] ## host
可选的性质:有时候你在匹配模式中包含了(),但是有什么内容并不是你想提取的,在这种情况下,在括号中的开头加上?:,例如(?: ),这样这个括号的内容将不会计入到结果中
参考链接:https://www.zybuluo.com/chanvee/note/87894
extract
df['Airline'] = df['Airline'].str.extract(
'([a-zA-Z\s]+)', expand=False).str.strip() #去除前后空白字符strip
FlightNumber RecentDelays Airline From To
0 10045 [23, 47] KLM London Paris
1 10055 [] Air France Madrid Milan
2 10065 [24, 43, 87] British Airways London Stockholm
3 10075 [13] Air France Budapest Paris
4 10085 [67, 32] Swiss Air Brussels London