目录
1. 学习内容
1. 了解string类型与object类型的区别
2. 学会string类型的各种处理方式
2. 准备工作
import pandas as pd
import numpy as np
3. string类型的性质与转换
3.1 string类型与object类型的区别
主要有3点:首先,string字符存取方法会返回相应数据的Nullable类型,而object会随缺失值的存在而改变返回类型;然后,某些Series方法不能在string上使用,例如Series.str.decode(),因为存储的是字符串而不是字节;最后,string类型在缺失值存储或运算时,类型会广播为pd.NA,而不是浮点型np.nan。
其余全部内容在当前版本下完全一致,但迎合pandas的发展模式,这里仍然全部用string来操作字符串。
3.2 string类型的转换
如果将一个其他类型的容器直接转换string类型可能会出错。当下正确的方法是分两部转换,先转为str型的object,再转为string类型。
pd.Series([1,'1.']).astype('str').astype('string')
0 1
1 1.
dtype: string
4. 拆分与拼接
4.1 str.split()方法
4.1.1 分割符与str的位置元素选取
s = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'], dtype = "string")
s
0 a_b_c
1 c_d_e
2 <NA>
3 f_g_h
dtype: string
s.str.split('_')
0 [a, b, c]
1 [c, d, e]
2 <NA>
3 [f, g, h]
dtype: object
这里需要注意split后的类型是object,因为现在Series中的元素已经不是string,而包含了list,且string类型只能含有字符串。
另外,对于str方法可以进行元素的选择,如果该单元格元素是列表,那么str[i]表示取出第i个元素,如果是单个元素,则先把元素转为列表再取出。
s.str.split('_').str[1]
0 b
1 d
2 <NA>
3 g
dtype: object
4.1.2 其他参数
expand参数控制了是否将列拆开,n参数代表最多分割多少次。
s.str.split('_', expand = True, n = 1)
0 1
0 a b_c
1 c d_e
2 <NA> <NA>
3 f g_h
4.2 str.cat()方法
str.cat()方法对于不同对象的作用结果并不相同,其中的对象包括:单列、双列、多列。对于单个Series而言,就是指所有的元素进行字符合并为一个字符串。其中可选sep分隔符参数,和缺失值替代字符na_rep参数;对于两个Series合并而言,是对应索引的元素进行合并。同样也有相应参数,需要注意的是两个缺失值会被同时替换;多列拼接可以分为表的拼接和多Series拼接。
s = pd.Series(['ab', None, 'd'], dtype = 'string')
s
0 ab
1 <NA>
2 d
dtype: string
s.str.cat()
'abd'
s.str.cat(sep = ',')
'ab,d'
s.str.cat(sep = ',', na_rep = '*')
'ab,*,d'
s2 = pd.Series(['24', None, None], dtype = 'string')
s2
0 24
1 <NA>
2 <NA>
dtype: string
s.str.cat(s2)
0 ab24
1 <NA>
2 <NA>
dtype: string
s.str.cat(s2, sep = ',', na_rep = '*')
0 ab,24
1 *,*
2 d,*
dtype: string
s.str.cat(pd.DataFrame({0:['1', '3', '5'], 1:['5', 'b', None]}, \
dtype = 'string'), na_rep = '*')
0 ab15
1 *3b
2 d5*
dtype: string
s.str.cat([s + '0', s * 2])
0 abab0abab
1 <NA>
2 dd0dd
dtype: string
s.str.cat(s2, na_rep = '*')
0 ab24
1 **
2 d*
dtype: string
5. 替换
广义上的替换,就是指str.replace()的应用,fillna是针对缺失值的替换。提到替换,就不可避免地接触到正则表达式,这里默认读者已掌握常见正则表达式知识点。
5.1 一般用法
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca','', np.nan, 'CABA', 'dog', 'cat'], \
dtype = "string")
s
0 A
1 B
2 C
3 Aaba
4 Baca
5
6 <NA>
7 CABA
8 dog
9 cat
dtype: string
s.str.replace(r'^[AB]', '***')
0 ***
1 ***
2 C
3 ***aba
4 ***aca
5
6 <NA>
7 CABA
8 dog
9 cat
dtype: string
5.2 子组与函数替换
# 通过正整数调用子组(0返回字符本身,从1开始才是子组)
s.str.replace(r'([ABC])(\w+)', lambda x: x.group(2))
0 A
1 B
2 C
3 aba
4 aca
5
6 <NA>
7 ABA
8 dog
9 cat
dtype: string
# 利用?P<....>表达式可以对子组命名调用
s.str.replace(r'(?P<one>[ABC])(?P<two>\w+)', lambda x: x.group('two'))
0 A
1 B
2 C
3 aba
4 aca
5
6 <NA>
7 ABA
8 dog
9 cat
dtype: string
5.3 注意事项
要明确str.replace和replace并不是一个东西:str.replace针对的是object类型或string类型,默认是以正则表达式为操作,目前暂时不支持DataFrame上使用。replace针对的是任意类型的序列或数据框,如果要以正则表达式替换,需要设置regex=True,该方法通过字典可支持多列替换。但现在由于string类型的初步引入,用法上出现了一些问题,这些问题可能会在以后的版本中修复。
更具体具体而言:str.replace()不可输入pd.NA(当前版本不可以),可以考虑先转换为object类型最后再换回来;对于string类型Series,在使用replace函数时不能使用正则表达式替换,该bug现在还未修复;string类型序列如果存在缺失值,不能使用replace替换,而要用str.replace。
综上,除非需要赋值元素为缺失值(转为object再转回来),否则请使用str.replace()方法。
6. 子串匹配与提取
这部分对正则表达式的要求相对较高,这里先不写了。
7. 常用字符串方法
这部分的方法与python3自带的字符串类型的方法很类似。具体有:str.strip(),str.lower(),str.upper(),str.swapcase(),str.capitalize()和str.isnumeric()方法。
8. 问题与练习
8.1 问题
【问题一】 str对象方法和df/Series对象方法有什么区别?
str.replace针对的是object类型或string类型,默认是以正则表达式为操作,目前暂时不支持DataFrame上使用。
replace针对的是任意类型的序列或数据框,如果要以正则表达式替换,需要设置regex=True,该方法通过字典可支持多列替换。
【问题二】 给出一列string类型,如何判断单元格是否是数值型数据?
正则表达式或者用str.isnumeric()
【问题三】 rsplit方法的作用是什么?它在什么场合下适用?
与split功能类似,只不过只对字符串的右边有效。
【问题四】 在本章的第二到第四节分别介绍了字符串类型的5类操作,请思考它们各自应用于什么场景?
拆分:某个字符串series里有相同的分隔符的时候,可以用split来分开。例如表示时间的数据。
拼接:理解为拆分的逆操作。
替换:进行数据清洗。
字串匹配:检查是否存在自己需要的模式字符串。
字串提取:当字符串series有一定的规律的时候,提取自己需要的模式。
8.2 练习
略。