pandas-string-in-chapter7

字符串操作

1
2
3
4
5
6
7
import numpy as np
import pandas as pd
pd.options.display.max_rows = 20
np.random.seed(12345)
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))
np.set_printoptions(precision=4, suppress=True)

字符串方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#分割
val = 'a,b, guido'
print(val.split(','))

#分割和清空格
pieces = [x.strip() for x in val.split(',') ]
print(pieces)

#拼接子字符串
first,second,third = pieces #赋值
print(first + "::" + second + "::" + third)
#用方法拼接
print("::".join(pieces))


#查找子字符串
#确认是否在字符串里
print('guido' in val)
#查找index,没有的话会报错
print(val.index(','))
#查找字符,返回index,没有的话则是-1
print(val.find(':'))
print(val.find(','))

#计算出现的次数
print(val.count(','))

#替换
print(val.replace(',','::'))
1
2
3
4
5
6
7
8
9
10
['a', 'b', '  guido']
['a', 'b', 'guido']
a::b::guido
a::b::guido
True
1
-1
1
2
a::b:: guido

方法表

方法 描述
count 计算各字符出现的次数
endswitch 如果结束子字符串是suffix,则返回True
startswitch 如果开始子字符串是prefix,则返回True
join 用自身字符串为分隔符,添加一组字符串
index 返回子字符串首字母的index位置,没找到则报错
find 返回子字符串首字母的index位置,没找到则返回-1
rfind 从右边开始查找,返回最末字母的位置
replace 替换
strip 消除两边的空白
rstrip 消除右边的空白
lstrip 消除左边的空白
split 根据分隔符分离
lower 小写
upper 大写
casefold 将字符转换为小写,并将任何特定于区域的变量字符组合转换为通用的可比较形式
ljust 左对齐,并用空格(或其他字符)填充另一侧
rjust 右对齐,并用空格(或其他字符)填充另一侧

正则

1
2
3
4
5
6
7
8
9
10
11
12
import re
text = "foo bar\t baz \tqux"
#re.split会自动编译正则表达式,之后在切分
#\s+为任何空白字符
print(re.split('\s+', text))

#自己编译后切分
regex = re.compile('\s+')
print(regex.split(text))

#找到所有空白处
print(regex.findall(text))

findall匹配所有,search只返回第一次匹配,mathc只匹配str的开头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
text = """Dave dave@google.com
Steve steve@gmail.com
Rob rob@gmail.com
Ryan ryan@yahoo.com
"""
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'

#re.IGNORECASE为不关心大小写
regex= re.compile(pattern,flags=re.IGNORECASE)

#findall
print(regex.findall(text))
#search
m = regex.search(text) #返回一个特殊match对象
print(m.start(),m.end())
print(text[m.start():m.end()]) #得到搜到的字符串

#match会匹配开头,如果开头不是所要匹配的则是None
print(regex.match(text))

#sub则会返回一个匹配字符被代替的新字符串
print(regex.sub('REDACTED',text)) #邮箱被指定的字符串代替


#re的分组,用()进行分组
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern,flags=re.IGNORECASE)
m = regex.match('wesm@bright.net')
print(m.groups())
print(regex.findall(text))
#sub可以用\1 \2等特殊字符来访问匹配的group
print(regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com']
5 20
dave@google.com
None
Dave REDACTED
Steve REDACTED
Rob REDACTED
Ryan REDACTED

('wesm', 'bright', 'net')
[('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')]
Dave Username: dave, Domain: google, Suffix: com
Steve Username: steve, Domain: gmail, Suffix: com
Rob Username: rob, Domain: gmail, Suffix: com
Ryan Username: ryan, Domain: yahoo, Suffix: com

正则表达式方法

方法 说明
findall 匹配所有,返回list
finditer 返回的是迭代
match 匹配开头,并且可以分组,匹配不成功返回None
search 匹配一次,返回对应的对象,可以匹配任意位置
split 根据regex来切分
sub,subn 代替匹配到的内容,可以用\\1 \\2等来表示group

矢量化字符串函数

1
2
3
4
5
6
7
8
9
10
11
data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',
'Rob': 'rob@gmail.com', 'Wes': np.nan}
data = pd.Series(data)
print(data)
print(data.isnull())

#为了处理NaN,使用series的st属性
print(data.str.contains('gmail'))

#str有同样的re方法
print(data.str.findall(pattern,flags=re.IGNORECASE))

矢量化字符串操作方法

方法 描述
cat 选择分隔符进行连接,sep指定分隔符
contains 返回一个bool,确定是否含有所填的子字符串或正则
count 计算子字符串出现次数,pat指定正则或者字符串
extract 使用正则的group,得到一个或多个字符串,并以每个group为列的df
endswitch 对每个元素用 x.endswith(pattern)
startswitch 对每个元素用 x.startswith(pattern)
findall 正则查找所有的元素
get 得到每个元素对应index的值,参数为int,超出index不会报错,返回NaN
isalnum 检测是否每个元素是字母和数字组成的
isalpha 检测是否每个元素是字母组成的
isdecimal 检测是否每个元素是数字
isdigit 检测是否每个元素是数字,包含一些特殊数字列如unicode的上下标数字
islower 检测是否每个元素是小写的
isnumeric 检测是否每个元素是数字
isupper 检测是否每个元素是大写的
join 在每个字符串中的每个元素之间添加分隔符
len 计算每个字符串的长度
lower,upper 把每个字符串变大写或小写
match 和正则match一样
pad 给个数字,添加空格到对应的长度,fillchar添加的字符,默认空格;size添加位置,默认left
center 等同于pad(size=’both’)
repeat 重复次数
replace 替换
slice 切片,start,stop,step
split 根据正则或分隔符进行分割
strip 两边去空格
rstrip 左边去空格
lstrip 右边去空格
1
2
3
4
5
6
7
8
data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com',
'Rob': 'rob@gmail.com', 'Wes': np.nan}
data = pd.Series(data)
print(data.str.cat(sep='|'))
print(data.str.contains('gmail'))
print(data.str.count('\w+'))
print(data.str.extract("(\w+)@(\w+)"))
print(data.str.join("|"))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
dave@google.com|steve@gmail.com|rob@gmail.com
Dave False
Steve True
Rob True
Wes NaN
dtype: object
Dave 3.0
Steve 3.0
Rob 3.0
Wes NaN
dtype: float64
0 1
Dave dave google
Steve steve gmail
Rob rob gmail
Wes NaN NaN
Dave d|a|v|e|@|g|o|o|g|l|e|.|c|o|m
Steve s|t|e|v|e|@|g|m|a|i|l|.|c|o|m
Rob r|o|b|@|g|m|a|i|l|.|c|o|m
Wes NaN
dtype: object