大部分文本运算都可以直接使用字符串对象的内置方法,对于复杂的模式匹配,可以使用正则表达式。

pandas对此进行强化,使其能够对整组数据应用字符串表达式和正则表达式,并能够处理缺失数据。

字符串对象方法

拆分字符串

val = 'a,b,  guido'
val.split(',')

split常结合strip使用

pieces = [x.strip() for x in val.split(',')]

利用+,可以将子字符串以双冒号分隔符形式连接起来

first, second, third = pieces
first + '::' + second + '::' + third

更为推荐的方式是使用join方法

'::'.join(pieces)

检测子串是否存在可以使用python的in关键字

'guido' in val

或者是使用index和find方法

val.index(',')
val.find(':')

如果index找不到,则抛出一个异常,而不是像find一样返回-1.

可以通过count方法,返回指定子串的出现次数

val.count(':')

replace用于替换

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

正则表达式

python内置的re模块负责对字符串应用正则表达式。而re模块的函数分为3类:模式匹配、替换、拆分

import re
text = "foo    bar\t baz  \tqux"
re.split('\s+', text)

调用re.split('\s+',text),正则表达式会先被编译,然后再在text上调用split方法。

通过re.compile编译regex得到可重用的对象

regex = re.compile('\s+')
regex.split(text)

查找正则表达式匹配的所有

regex.findall(text)

match、search、findall功能类似,findall返回的是字符串中所有的匹配项,而search只返回第一个匹配项,而match只匹配字符串的首部。

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}'

# re.IGNORECASE makes the regex case-insensitive
regex = re.compile(pattern, flags=re.IGNORECASE)
regex.findall(text)
m = regex.search(text)
text[m.start():m.end()]

此时match方法返回none

print(regex.match(text))

sub方法可以将匹配的模式替换为指定的字符串

print(regex.sub('REDACTED', text))

上面是找寻电子邮件地址,现在将地址分为3个部分:用户名、域名和域名后缀

pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern, flags=re.IGNORECASE)
m = regex.match('[email protected]')
m.groups()

此时findall会返回一个元组列表

regex.findall(text)

sub可以通过\1、\2等特殊符号访问匹配项中的分组

print(regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text))

pandas中矢量化的字符串函数

data = {'Dave': '[email protected]', 'Steve': '[email protected]',
        'Rob': '[email protected]', 'Wes': np.nan}
data = Series(data)
data.isnull()

检查各个电子邮件地址是否含有gmail

data.str.contains('gmail')

或者是使用正则表达式

data.str.findall(pattern, flags=re.IGNORECASE)

获取矢量化元素

matches = data.str.match(pattern, flags=re.IGNORECASE)
matches.str.get(1)
matches.str[0]

或者是

data.str[:5]

results matching ""

    No results matching ""