目录
string 类型的性值
拆分和拼接
替换
子串匹配与提取
常用字符串方法
问题与练习
s=pd.Series([1,1.])
print(s)
s.astype('string')
输出
0 1.0
1 1.0
dtype: float64
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in ()
#先转化为object类型,在转化为string
s.astype('str').astype('string')
0 1.0
1 1.0
dtype: string
s.str.split(pat=None, n=-1, expand=False) #str.split方法必须时字符串
s=pd.Series(['a b c',np.nan,'f_g_h'],dtype='string')
print(s)
print(s.str.split())
print(s.str.split('_'))
a b c
1
2 f_g_h
dtype: string
0 [a, b, c]
1
2 [f_g_h]
dtype: object
0 [a b c]
1
2 [f, g, h]
print(s.str.split('_').str[0])
0 a b c
1
2 f
dtype: object
pd.Series(['a_b_c',['a','b','c']],dtype='string')
这样会报错,string类型必须是字符串或者包含NaN
str方法: 可以进行元素的选择,如果该单元格元素是列表,那么str[i]表示取出第i个元素,如果是单个元素,则先把元素转化为列表在取出
print(s)
print(s.str.split('_').str[1])
print(s.str[0])
0 a_b_c
1
2 c_d_e
dtype: string
0 b
1
2 d
dtype: object
0 a
1
2 c
dtype: string
s=pd.Series(['a_b_c',['a','b','c']],dtype='object')
print(s)
s.str[1]
0 a_b_c
1 [a, b, c]
dtype: object
0 _
1 b
dtype: object
#expand 参数控制了是否将列拆开,n表述最多分隔多少次
s.str.split('_',expand=True)
结果: 0 1 2
0 a b c
1 NaN NaN NaN
s.str.split('_',expand=True,n=1)
结果:
0 1
0 a b_c
1 NaN NaN
s=pd.Series(['ab',None,'d'],dtype='string')
print(s)
结果
0 ab
1
2 d
dtype: string
print(s.str.cat())
结果:
abd
sep分隔参数,缺失值替代字符na_sep
s.str.cat(sep=',')
结果:'ab,d'
s.str.cat(sep=',',na_rep='*')
结果 'ab,*,d'
对于两个Series合并,是对应索引的元素进行合并
s2=pd.Series(['24',None,None],dtype='string')
print('s2\n',s2)
print('cat:\n',s.str.cat())
s2
0 24
1
2
dtype: string
cat:
abd
多列拼接剋分为表的拼接和Series的拼接
表的拼接
print(s)
s3=pd.DataFrame({0:['1','3','5'],1:['5','b',None]},dtype='string')
print(s3)
s.str.cat(s3,na_rep='*')
结果:
0 ab
1
2 d
dtype: string
0 1
0 1 5
1 3 b
2 5
0 ab15
1 *3b
2 d5*
dtype: string
多个Series的拼接
s.str.cat([s+'0',s*2,s*3])
0 abab0ababababab
1
2 dd0ddddd
dtype: string
cat 的索引对齐
当前版本如果两边的索引不相同且未指定join参数,默认左连接,设置join=‘left
print(s)
s2=pd.Series(list('abc'),index=[1,2,3],dtype='string')
print(s2)
print(s.str.cat(s2,na_rep='*'))
结果
0 ab
1
2 d
dtype: string
1 a
2 b
3 c
dtype: string
0 ab*
1 *a
2 db
dtype: string
s=pd.Series(['A','B','C','Aaba','',np.nan,'CANB','dog','cat'],dtype='string')
print(s)
print(s.str.replace(r'^[AB]','**'))
# ^[AB]以A或者B开头
结果:
0 A
1 B
2 C
3 Aaba
4
5
6 CANB
7 dog
8 cat
dtype: string
0 **
1 **
2 C
3 **aba
4
5
6 CANB
7 dog
8 cat
dtype: string
print(s)
s.str.replace(r'([ABC])(\w+)',lambda x:x.group(2)[1:]+'*')
结果:
0 A
1 B
2 C_
3 Aaba
4
5
6 CANB
7 dog
8 cat
dtype: string
0 A
1 B
2 *
3 ba*
4
5
6 NB*
7 dog
8 cat
dtype: string
s.str.replace(r'(?P[ABC])(?P\w+)',lambda x:x.group('two')[1:]+'*')
结果:
0 A
1 B
2 *
3 ba*
4
5
6 NB*
7 dog
8 cat
dtype: string
#str.replace赋值参数不得为pd.NA
# print(pd.Series(['A','B'],dtype='string').str.replace(r'[A]',pd.NA))
pd.Series(['A','B'],dtype='string').astype('O').replace(r'[A]',pd.NA,regex=True).astype('string')
print(pd.Series(['A','B'],dtype='string').replace(r'[A]','C',regex=True))
print(pd.Series(['A','B'],dtype='O').replace(r'[A]','C',regex=True))
0 A
1 B
dtype: string
0 C
1 B
dtype: object
pd.Series(['10-87','10-88'],dtype='string').str.extract(r'([\d]{2})-([\d]{2})')
结果
0 1
0 10 87
1 10 88
pd.Series(['10-87','10-88','-89'],dtype='string').str.extract(r'(?P[\d]{2})-(?P[\d]{2})')
结果
name_1 name_2
0 10 87
1 10 88
2
pd.Series(['10-87','10-88','-89'],dtype='string').str.extract(r'(?P[\d]{2})?-(?P[\d]{2})')
name_1 name_2
0 10 87
1 10 88
2 89
1
s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"], dtype="string")
s
输出:
A11 a1
B22 b2
C33 c3
dtype: string
s.str.extract(r'([\w])')
结果
0
A11 a
B22 b
C33 c
s.str.extract(r'([\w])',expand=False)
结果
A11 a
B22 b
C33 c
dtype: string
s.str.extract(r'([\w])([\d])')
0 1
A11 a 1
B22 b 2
C33 c 3
s.index.str.extract(r'([\w])([\d])',expand=False) #报错
ValueError: only one regex group is supported with Index
str.extractall方法
与 extract只匹配一个符合条件的表达式不同,extractall会找出所有符合条件的字符串,并建立多级索引
s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"],dtype="string")
# print(s)
two_groups = '(?P[a-z])(?P[0-9])'
s.str.extract(two_groups, expand=True)
letter digit
A a 1
B b 1
C c 1
s.str.extractall(two_groups)
输出
letter digit
match
A 0 a 1
1 a 2
B 0 b 1
C 0 c 1
如果想查看第i层匹配,可使用xs方法
s = pd.Series(["a1a2", "b1b2", "c1c2"], index=["A", "B", "C"],dtype="string")
s.str.extractall(two_groups)
letter digit
match
A 0 a 1
1 a 2
B 0 b 1
1 b 2
C 0 c 1
1 c 2
s.str.extractall(two_groups).xs(0,level='match')
letter digit
A a 1
B b 1
C c 1
s.str.extractall(two_groups).xs(1,level='match')
letter digit
A a 2
B b 2
C c 2
str.contains 检测是否包含某种正则模式
pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains(r'[0-9][a-z]')
0 False
1
2 True
3 True
4 True
dtype: boolean
#将空设置为false
pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains('a', na=False)
0 False
1 False
2 True
3 False
4 False
dtype: boolean
pd.Series(['1', None, '3a_', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]',na=False)
0 False
1 False
2 True
3 True
4 False
dtype: boolean
s=pd.Series(list('abc'),index=[' space1 ','space2 ',' space3'],dtype="string")
print(s.index)
s.index.str.strip()
Index([' space1 ', 'space2 ', ' space3'], dtype='object')
Index(['space1', 'space2', 'space3'], dtype='object')
pd.Series('A',dtype="string").str.lower()
输出
0 a
dtype: string
pd.Series('a',dtype="string").str.upper()
输出:
0 A
dtype: string
pd.Series(['1.2','1','-0.3','a',np.nan],dtype="string").str.isnumeric()
0 False
1 True
2 False
3 False
4
dtype: boolean
pd.Series(['1.2','1','-0.3','a',np.nan,1]).apply(lambda x:True if type(x)in [float,int] and x==x else False)
拆分.str.split()比如2019年,我们只关注2019
拼接.str.cat() 将几列拼接成一列
替换.str.replace()将Na替换成特定的值,比如众数
匹配.str.contains() .str.match() 查找包含特定值的
提取.str.extract() .str.extractall() 查找每个元素中特定的正则表达式的格式的内容并提取出来
练习
pd.DataFrame(d.姓名+','+d.国籍+'国人,'+'性别:'+d.性别+','+'出生于'+d.出生年+'年'+d.出生月+'月'+d.出生日+'日')
d=pd.read_csv('data/String_data_two.csv').head()
d.head()
d[d.col1.str.contains('北京|上海')]
输出:
col1 col2 col3
4 上海开学日期延至3月 -95 4.05
d.col2.astype('int').mean()
d.columns=d.columns.str.strip()
d.columns
d.col3.astype('float').mean()
应该是存在问题,怎么可能出这么简单的/。。。。。。等着去看下参考答案。