Pandas中的文本处理
向量化的字符串处理方法
- Pandas的字符串属的方法几乎包括了大部分Python的内置字符串方法(内置共有45个方法),下面将列举一些常见的方法的用法
- 只能用于series,不能直接用于整个数据框
方法 |
说明 |
len() |
计算字符串长度 |
strip() |
等价于str.strip,去除字符串开头和结尾处指定的字符 |
rstrip() |
等价于str.rstrip ,删除字符串末尾的指定字符(默认为空格) |
lstrip() |
等价于str.lstrip,截掉字符串左边的空格或指定字符 |
partition() |
等价于str.partition,根据指定的分隔符(sep)将字符串进行分割,从左边开始 |
rpartition() |
等价于str.rpartition,根据指定的分隔符(sep)将字符串进行分割,从右边开始 |
lower() |
等价于str.lower,所有大写字母转换为小写字母,仅限英文 |
casefold() |
等价于str.casefold,所有大写字母转换为小写字母,包括非英文 |
upper() |
等价于str.upper,小写字母转换为大写字母 |
find() |
等价于str.find,查找字符串中指定的子字符串sub第一次出现的位置 |
rfind() |
等价于str.rfind,查找字符串中指定的子字符串sub最后一次出现的位置 |
index() |
等价于str.index,查找字符串中第一次出现的子字符串的位置 |
rindex() |
等价于str.rindex,返回子字符串最后一次出现在字符串中的索引位置 |
capitalize() |
等价于str.capitalize,将字符串的第一个字母变成大写,其余字母变为小写 |
swapcase() |
等价于str.swapcase,将字符串str中的大小写字母同时进行互换 |
normalize() |
返回Unicode 标注格式。等价于 unicodedata.normalize |
translate() |
等价于str.translate,根据maketrans()函数给出的字符映射表来转换字符 |
isalnum() |
等价于str.isalnum,检测字符串是否由字母和数字组成 |
isalpha() |
等价于str.isalpha,检测字符串是否只由字母组成 |
isdigit() |
等价于str.isdigit,检测字符串是否只由数字组成 |
isspace() |
等价于str.isspace,检测字符串是否只由空格组成 |
islower() |
等价于str.islower,检测字符串中的字母是否全由小写字母组成 |
isupper() |
等价于str.isupper,检测字符串中的字母是否全由大写字母组成 |
istitle() |
等价于str.istitle,检测所有单词首字母是否为大写,且其它字母是否为小写 |
isnumeric() |
等价于str.isnumeric,测字符串是否只由数字组成 |
isdecimal() |
等价于str.isdecimal,检查字符串是否只包含十进制字符 |
startswith() |
等价于str.startswith(pat),判断字符串是否以指定字符或子字符串开头 |
endswith() |
等价于str.endswith(pat),判断字符串是否以指定字符或子字符串结尾 |
center() |
等价于str.center,即字符串str居中,两边用字符填充 |
ljust() |
等价于str.ljust,左对齐填充,并使用fillchar填充(默认为空格) |
rjust() |
等价于str.rjust,右对齐填充,默认为空格 |
zfill() |
等价于str.zfill,右对齐,前面用0填充到指定字符串长度 |
#len
#计数
import pandas as pd
import numpy as np
s = pd.Series(['amazon','alibaba','Baidu'])
s.str.len()
0 6
1 7
2 5
#lower()
#大小写转换,转换成小写字母
s = pd.Series(['Amazon','alibaba','Baidu'])
s.str.lower()
0 amazon
1 alibaba
2 baidu
#zfill()
#右对齐,前面用0填充到指定字符串长度
s = pd.Series(['56783','34','987766721','326'])
s.str.zfill(10)
"""
0 0000056783
1 0000000034
2 0987766721
3 0000000326
"""
split()
- split,按指定字符或表达式分割字符串,类似split的方法返回一个列表类型的序列
#按数字分割
s = pd.Series(['QQ1252号码','QQ1353加我','我389的'])
s.str.split('\d+')
0 [QQ, 号码]
1 [QQ, 加我]
2 [我, 的]
# 按固定字符分割
s = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'])
s.str.split('_')
0 [a, b, c]
1 [c, d, e]
2 NaN
3 [f, g, h]
#切分后的列表中的元素可以通过get方法或者 [] 方法进行读取
s.str.split('_').str.get(1)
Out[96]:
0 b
1 d
2 NaN
3 g
#使用expand方法可以轻易地将这种返回展开为一个数据表
s.str.split('_', expand=True)
0 1 2
0 a b c
1 c d e
2 NaN NaN NaN
3 f g h
#同样,我们也可以限制切分的次数:
s.str.split('_', expand=True, n=1)
0 1
0 a b_c
1 c d_e
2 NaN NaN
3 f g_h
rsplit()
- rsplit与split相似,不同的是,这个切分的方向是反的,即从字串的尾端向首段切分
s = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'])
s.str.rsplit('_', expand=True, n=1)
0 1
0 a_b c
1 c_d e
2 NaN NaN
3 f_g h
replace ()
#参数解释
"""
pat:str 或编译的正则表达式,字符串可以是字符序列或正则表达式。
case:布尔值,默认无。确定替换是否区分大小写:
regex:布尔值,默认为真。确定 passed-in 模式是否为正则表达式:
"""
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca','', np.nan, 'CABA', 'dog', 'cat'])
s.str.replace('^.a|dog', 'XX-XX ', case=False)
Out[27]:
0 A
1 B
2 C
3 XX-XX ba
4 XX-XX ca
5
6 NaN
7 XX-XX BA
8 XX-XX
9 XX-XX t
pd.Series(['foo', 'fuz', np.nan]).str.replace('f.', 'ba', regex=True)
0 bao
1 baz
2 NaN
pd.Series(['f.o', 'fuz', np.nan]).str.replace('f.', 'ba', regex=False)
0 bao
1 fuz
2 NaN
findall()
#基础用法
Series.str.findall(pat, flags=0)
#参数解释
pat:正则表达式
flags:Flags from re module, e.g. re.IGNORECASE (default is 0, which means no flags),是否忽略大小写。
import re
#提取聊天记录中的QQ号
s=pd.Series(['QQ号码123452124','QQ123356123','我的Q123356189','Q号123356111注意','加我Q号123356124有惊喜'])
s.str.findall('\d+')
0 [123452124]
1 [123356123]
2 [123356189]
3 [123356111]
4 [123356124]
s.str.findall('Q')
0 [Q, Q]
1 [Q, Q]
2 [Q]
3 [Q]
4 [Q]
s.str.findall('q')
0 []
1 []
2 []
3 []
4 []
s.str.findall('q', flags=re.IGNORECASE)
0 [Q, Q]
1 [Q, Q]
2 [Q]
3 [Q]
4 [Q]
其他向量化的方法
- 除了上面介绍的Pandas字符串的正常操作和正则表达式外,Pandas的str属性还提供了其他的一些方法,这些方法非常的有用,在进行特征提取或者数据清洗时,非常高效,具体如下:
方法 |
说明 |
get() |
获取元素索引位置上的值,索引从0开始 |
slice() |
对元素进行切片取值 |
slice_replace() |
对元素进行切片替换 |
cat() |
连接字符串 |
repeat() |
重复元素 |
normalize() |
将字符串转换为Unicode规范形式 |
pad() |
在字符串的左边右边或者两边增加空格 |
wrap() |
将字符串按照指定的宽度换行 |
join() |
用分隔符连接Series对象的每个元素 |
get_dummies() |
按照分隔符提取每个元素的dummy变量,转换为one-hot编码的DataFrame |
#wrap() <<<<<=================================
#处理长文本数据(段落或消息)时,Pandas str.wrap()是一种重要的方法。当它超过传递的宽度时,用于将长文本数据分发到新行中或处理制表符空间
s = pd.Series(['0000056783','0000000034','0987766721'])
s.str.wrap(5)
"""
0 00000\n56783
1 00000\n00034
2 09877\n66721
print('09877\n66721')
09877
66721
"""
#pad() <<<<<=================================
#Pandas 提供了一种向系列中的每个字符串元素添加填充(空格或其他字符)的方法。每次调用.str时都必须加上前缀,以区别于Python的默认函数,否则会引发错误。
# 默认从左边开始填充
s = pd.Series(['A','E','C','D','E'])
s.str.pad(5 ,fillchar='x')
0 xxxxA
1 xxxxE
2 xxxxC
3 xxxxD
4 xxxxE
# 从右边开始填充
s.str.pad(5 ,side='right',fillchar='x')
0 Axxxx
1 Exxxx
2 Cxxxx
3 Dxxxx
4 Exxxx
# 默认为空格
s.str.pad(5)
Out[65]:
0 A
1 E
2 C
3 D
4 E
#slice() <<<<<=================================
#Pandas str.slice()方法用于从Pandas系列对象中存在的字符串中分割子字符串。它非常类似于Python在[start:stop:step]上进行切片的基本原理,这意味着它需要三个参数,即开始位置,结束位置和要跳过的元素数量
s = pd.Series(['马 云:2000亿','马化腾:1800亿','王健林:1200亿','小伍哥:0.000012亿'])
s.str.slice(0,3)
0 马 云
1 马化腾
2 王健林
3 小伍哥
s = pd.Series(["koala", "dog", "chameleon"])
s
0 koala
1 dog
2 chameleon
s.str.slice(start=1)
0 oala
1 og
2 hameleon
s.str.slice(start=-1)
0 a
1 g
2 n
s.str.slice(stop=2)
0 ko
1 do
2 ch
s.str.slice(step=2)
0 kaa
1 dg
2 caeen
s.str.slice(start=0, stop=5, step=3)
0 kl
1 d
2 cm
s.str[0:5:3]
0 kl
1 d
2 cm
#get() <<<<<=================================
#使用Pandas str.get()方法获取通过位置的元素。此方法适用于整个系列中的字符串,数值甚至列表。每次都必须给.str加上前缀
#参数解释i:要提取的元素的位置,仅整数值
s = pd.Series(['马 云:2000亿','马化腾:1800亿','王健林:1200亿','小伍哥:0.000012亿'])
s.str.get(0)
0 马
1 马
2 王
3 小
s = pd.Series(["String",
(1, 2, 3),
["a", "b", "c"],
123,
-456,
{1: "Hello", "2": "World"}])
s.str.get(1)
0 t
1 2
2 b
3 NaN
4 NaN
5 Hello
#slice_replace() <<<<<=================================
#用另一个值替换字符串的位置切片
s = pd.Series(['马 云:2000亿','马化腾:1800亿','王健林:1200亿','小伍哥:0.000012亿'])
#切片替换
s.str.slice_replace(0,3,'小伍哥')
0 小伍哥:2000亿
1 小伍哥:1800亿
2 小伍哥:1200亿
3 小伍哥:0.000012亿
s.str.join('-')
0 马- -云-:-2-0-0-0-亿
1 马-化-腾-:-1-8-0-0-亿
2 王-健-林-:-1-2-0-0-亿
3 小-伍-哥-:-0-.-0-0-0-0-1-2-亿
#repeat() <<<<<=================================
s = pd.Series(['A','E','C','D','E'])
s.str.repeat(2)
0 AA
1 EE
2 CC
3 DD
4 EE
# 不同的行重复不同的次数
s.str.repeat(repeats=[1, 2, 3])
0 a
1 bb
2 ccc
#cat()
#连接字符串,对于不同对象的作用结果并不相同,其中的对象包括:单列、双列、多列
如果连接的是两个序列,则会一一对应连接
s1 = pd.Series(['A','E','C','D','E'])
s2 = pd.Series(['1','2','3','4','5'])
s1.str.cat(s2)
0 A1
1 E2
2 C3
3 D4
4 E5
#只提供一个序列,则只连接自己,默认为空格
s1.str.cat()
'AECDE'
s1.str.cat(sep='-')
'A-E-C-D-E'
#也可以同时复核连接,参数可以是二维的
d = pd.concat([s1, s2], axis=1)
s3 = pd.Series(['x','x','y','y','y'])
s3.str.cat(d, na_rep='-')
0 xA1
1 xE2
2 yC3
3 yD4
4 yE5
# 缺失值处理
s = pd.Series(['a', 'b', np.nan, 'd'])
s.str.cat(sep=' ')
'a b d'
s.str.cat(sep=' ', na_rep='?')
'a b ? d'