文本数据是指不能参与算术运算的任何字符,也称为字符型数据。如英文字母、汉字、不做为数值使用的数字(以单引号开头)和其余可输入的字符。python
文本数据具备数据维度高、数据量大且语义复杂等特色,是一种较为复杂的数据类型。今天,咱们就来一块儿看看如何使用Pandas对文本数据进行数据处理。git
本文目录
正则表达式
1. string类型的性质api
1.1. string与object的区别app
1.2. string类型的转换ide
2. 拆分与拼接函数
2.1. str.split方法编码
2.2. str.cat方法spa
3. 替换3d
3.1. str.replace的常见用法
3.2. 子组与函数替换
3.3. 关于str.replace的注意事项
4. 字串匹配与提取
4.1. str.extract方法
4.2. str.extractall方法
4.3. str.contains和str.match
5. 经常使用字符串方法
5.1. 过滤型方法
5.2. isnumeric方法
6. 问题及练习
6.1. 问题
6.2. 练习
首先,导入须要使用的包
import pandas as pdimport numpy as np
#pd.Series([1,'1.']).astype('string') #报错#pd.Series([1,2]).astype('string') #报错#pd.Series([True,False]).astype('string') #报错
pd.Series([1,'1.']).astype('str').astype('string')
0 1
1 1
dtype: string
pd.Series([1,2]).astype('str').astype('string')
0 1
1 2
dtype: string
pd.Series([True,False]).astype('str').astype('string')
0 True
1 False
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 <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
s.str.split('_').str[1]
0 b
1 d
2 <NA>
3 g
dtype: object
pd.Series(['a_b_c', ['a','b','c']], dtype="object").str[1] #第一个元素先转为['a','_','b','_','c']
0 _
1 b
dtype: object
s.str.split('_',expand=True)
s.str.split('_',n=1)
0 [a, b_c]
1 [c, d_e]
2 <NA>
3 [f, g_h]
dtype: object
s.str.split('_',expand=True,n=1)
2.2 str.cat方法
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
s2 = pd.Series(list('abc'),index=[1,2,3],dtype='string')s2
1 a
2 b
3 c
dtype: string
s.str.cat(s2,na_rep='*')
0 ab*
1 *a
2 db
dtype: string
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
s.str.replace(r'([ABC])(\w+)',lambda x:x.group(2)[1:]+'*')
0 A
1 B
2 C
3 ba*
4 ca*
5
6 <NA>
7 BA*
8 dog
9 cat
dtype: string
s.str.replace(r'(?P<one>[ABC])(?P<two>\w+)',lambda x:x.group('two')[1:]+'*')
0 A
1 B
2 C
3 ba*
4 ca*
5
6 <NA>
7 BA*
8 dog
9 cat
dtype: string
#pd.Series(['A','B'],dtype='string').str.replace(r'[A]',pd.NA) #报错#pd.Series(['A','B'],dtype='O').str.replace(r'[A]',pd.NA) #报错
pd.Series(['A','B'],dtype='string').astype('O').replace(r'[A]',pd.NA,regex=True).astype('string')
0 <NA>
1 B
dtype: string
pd.Series(['A','B'],dtype='string').replace(r'[A]','C',regex=True)
0 A
1 B
dtype: string
pd.Series(['A','B'],dtype='O').replace(r'[A]','C',regex=True)
0 C
1 B
dtype: object
#pd.Series(['A',np.nan],dtype='string').replace('A','B') #报错
pd.Series(['A',np.nan],dtype='string').str.replace('A','B')
0 B
1 <NA>
dtype: string
pd.Series(['10-87', '10-88', '10-89'],dtype="string").str.extract(r'([\d]{2})-([\d]{2})')
使用子组名做为列名
pd.Series(['10-87', '10-88', '-89'],dtype="string").str.extract(r'(?P<name_1>[\d]{2})-(?P<name_2>[\d]{2})')
利用?正则标记选择部分提取
pd.Series(['10-87', '10-88', '-89'],dtype="string").str.extract(r'(?P<name_1>[\d]{2})?-(?P<name_2>[\d]{2})')
pd.Series(['10-87', '10-88', '10-'],dtype="string").str.extract(r'(?P<name_1>[\d]{2})-(?P<name_2>[\d]{2})?')
(b)expand参数(默认为True)
s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"], dtype="string")s.index
Index(['A11', 'B22', 'C33'], dtype='object')
s.str.extract(r'([\w])')
s.str.extract(r'([\w])',expand=False)
A11 a
B22 b
C33 c
dtype: string
s.index.str.extract(r'([\w])')
s.index.str.extract(r'([\w])',expand=False)
Index(['A', 'B', 'C'], dtype='object')
s.index.str.extract(r'([\w])([\d])')
#s.index.str.extract(r'([\w])([\d])',expand=False) #报错
s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"],dtype="string")two_groups = '(?P<letter>[a-z])(?P<digit>[0-9])'s.str.extract(two_groups, expand=True)
s.str.extractall(two_groups)
s['A']='a1's.str.extractall(two_groups)
若是想查看第i层匹配,可以使用xs方法
s = pd.Series(["a1a2", "b1b2", "c1c2"], index=["A", "B", "C"],dtype="string")s.str.extractall(two_groups).xs(1,level='match')
4.3 str.contains和str.match
pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains(r'[0-9][a-z]')
0 False
1 <NA>
2 True
3 True
4 True
dtype: boolean
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
pd.Series(['1', None, '_3a', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]',na=False)
0 False
1 False
2 False
3 True
4 False
dtype: boolean
pd.Series(list('abc'),index=[' space1 ','space2 ',' space3'],dtype="string").index.str.strip()
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('abCD',dtype="string").str.swapcase()
0 ABcd
dtype: string
pd.Series('abCD',dtype="string").str.capitalize()
0 Abcd
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 <NA>
dtype: boolean
# 方法一> ex1_ori = pd.read_csv('data/String_data_one.csv',index_col='人员编号')> ex1_ori.head() 姓名 国籍 性别 出生年 出生月 出生日人员编号 1 aesfd 2 男 1942 8 102 fasefa 5 女 1985 10 43 aeagd 4 女 1946 10 154 aef 4 男 1999 5 135 eaf 1 女 2010 6 24
> ex1 = ex1_ori.copy()> ex1['冒号'] = ':'> ex1['逗号'] = ','> ex1['国人'] = '国人'> ex1['性别2'] = '性别'> ex1['生于'] = '生于'> ex1['年'] = '年'> ex1['月'] = '月'> ex1['日'] = '日'> ID = ex1['姓名'].str.cat([ex1['冒号'], ex1['国籍'].astype('str'), ex1['国人'], ex1['逗号'], ex1['性别2'], ex1['性别'], ex1['逗号'], ex1['生于'], ex1['出生年'].astype('str'), ex1['年'], ex1['出生月'].astype('str'), ex1['月'], ex1['出生日'].astype('str'), ex1['日'] ])> ex1_ori['ID'] = ID> ex1_ori 姓名 国籍 性别 出生年 出生月 出生日 ID人员编号 1 aesfd 2 男 1942 8 10 aesfd:2国人,性别男,生于1942年8月10日2 fasefa 5 女 1985 10 4 fasefa:5国人,性别女,生于1985年10月4日3 aeagd 4 女 1946 10 15 aeagd:4国人,性别女,生于1946年10月15日4 aef 4 男 1999 5 13 aef:4国人,性别男,生于1999年5月13日5 eaf 1 女 2010 6 24 eaf:1国人,性别女,生于2010年6月24日
# 参考答案> dic_year = {i[0]:i[1] for i in zip(list('零一二三四五六七八九'),list('0123456789'))}> dic_two = {i[0]:i[1] for i in zip(list('十一二三四五六七八九'),list('0123456789'))}> dic_one = {'十':'1','二十':'2','三十':'3',None:''}> df_res = df_new['ID'].str.extract(r'(?P<姓名>[a-zA-Z]+):(?P<国籍>[\d])国人,性别(?P<性别>[\w]),生于(?P<出生年>[\w]{4})年(?P<出生月>[\w]+)月(?P<出生日>[\w]+)日')> df_res['出生年'] = df_res['出生年'].str.replace(r'(\w)+',lambda x:''.join([dic_year[x.group(0)[i]] for i in range(4)]))> df_res['出生月'] = df_res['出生月'].str.replace(r'(?P<one>\w?十)?(?P<two>[\w])',lambda x:dic_one[x.group('one')]+dic_two[x.group('two')]).str.replace(r'0','10')> df_res['出生日'] = df_res['出生日'].str.replace(r'(?P<one>\w?十)?(?P<two>[\w])',lambda x:dic_one[x.group('one')]+dic_two[x.group('two')]).str.replace(r'^0','10')> df_res.head() 姓名 国籍 性别 出生年 出生月 出生日人员编号 1 aesfd 2 男 1942 8 102 fasefa 5 女 1985 10 43 aeagd 4 女 1946 10 154 aef 4 男 1999 5 135 eaf 1 女 2010 6 24
【练习二】 现有一份半虚拟的数据集,第一列包含了新型冠状病毒的一些新闻标题,请解决如下问题:
ex2.col2.str.rstrip('-`').str.lstrip('/').astype(float).mean()
-0.984
ex2.columns = ex2.columns.str.strip(' ')
## !!!用于寻找脏数据def is_number(x): try: float(x) return True except (SyntaxError, ValueError) as e: return Falseex2[~ex2.col3.map(is_number)]
ex2.col3.str.replace(r'[`\\{]', '').astype(float).mean()