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