Pandas中的文本处理

Pandas中的文本处理

参考来源:Pandas玩转文本处理! (qq.com)

向量化的字符串处理方法

  • 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'
posted @ 2023-03-31 16:58  小杨的冥想课  阅读(65)  评论(0编辑  收藏  举报