说明:本片博文接上篇博文【Pandas数据预处理之数据转换(哑变量编码pd.get_dummies())】以及上上篇博文【 Pandas数据预处理之数据转换(df.map()、df.replace())】
字符串和文本处理通常是由一些内置的字符串方法指定,一般语法格式为:series.str.method。其中,str.method被称为矢量化的字符串方法,包括str.upper()、str.lower()、str.split()等一系列字符串的内置方法,还可以结合正则化式进行处理。
(1)矢量化的字符串方法将对Series或者Index中的每个元素都进行相同的处理;
说明:缺失值不做任何处理
>>> s = pd.Series(['ADJruK','hjuQ',np.nan,'hj'])
>>> s
0 ADJruK
1 hjuQ
2 NaN
3 hj
dtype: object
>>> s.str.upper()
0 ADJRUK
1 HJUQ
2 NaN
3 HJ
dtype: object
(2)对于Index对象也可以使用矢量化字符串的处理方式;
>>> df = pd.DataFrame(np.random.randint(10,size=(2,3)),columns=['Jack Joe','BOB Marly','sid Jane'])
>>> df
Jack Joe BOB Marly sid Jane
0 4 1 4
1 9 1 8
#将所有列名转化为小写
>>> df.columns = df.columns.str.lower()
>>> df
jack joe bob marly sid jane
0 4 1 4
1 9 1 8
(3)链式法则(chain rules):将多个数据规整写在一行代码中;
#将所有列名转化为小写,再使用下划线代替空格
>>> df.columns = df.columns.str.lower().str.replace(' ','_')
>>> df
jack_joe bob_marly sid_jane
0 4 1 4
1 9 1 8
(4)分割元素:str.split()可以将一个Series对象规整为包含多个Series对象或DataFrame对象;
例:需求为提取每个元素的姓名---使用str.get方法或世界在str上进行索引
#创建一个Series对象
>>> ss = pd.Series(['name1 sex1 age1','name2 sex2 age2','name3 sex3 age3'])
>>> ss
0 name1 sex1 age1
1 name2 sex2 age2
2 name3 sex3 age3
dtype: object
>>> new_ss = ss.str.split(" ")
>>> new_ss
0 [name1, sex1, age1]
1 [name2, sex2, age2]
2 [name3, sex3, age3]
>>> type(new_ss)
<class 'pandas.core.series.Series'>
>>> new_ss.shape
(3,)
>>> new_ss[0]
['name1', 'sex1', 'age1']
#方法一:直接在str属性上使用索引(即str[]),即可提取每个样本的姓名
>>> new_ss.str[0]
0 name1
1 name2
2 name3
dtype: object
#方法二:使用str.get方法(即str.get()),即可提取每个样本的姓名
>>> new_ss.str.get(0)
0 name1
1 name2
2 name3
dtype: object
expand参数将分隔开的各个部分展开
>>> ss.str.split(" ",expand = True)
0 1 2
0 name1 sex1 age1
1 name2 sex2 age2
2 name3 sex3 age3
(5)结合正则表达式
Series.str属性结合正则表达式可以匹配一定模式的字符的换的提取、判断、替换等操作。
这些矢量化的字符串包括str.contains(查看是否包含指定的信息)、str.findall(提取指定的信息)、str.match、str.relpace(替换)和str.extract(指定捕获组以提取某信息)等等
以爬取的“58同城网重庆市南岸区二手房数据中的楼层数(floors)”为例。
>>> data = pd.read_csv('./input/data.csv',encoding = 'utf8')
>>> data = data['floors']
>>> data.head()
0 中层(共16层)
1 中层(共31层)
2 中层(共33层)
3 中层(共33层)
4 高层(共28层)
Name: floors, dtype: object
使用str.contains()找到其中包含数字的元素
>>> data.str.contains(r'\d')[:5]
0 True
1 True
2 True
3 True
4 True
使用str.repalce()对楼层进行加密(即将数字替换成'XX')
>>> data.str.replace(r'\d.','XX')[:5]
0 中层(共XX层)
1 中层(共XX层)
2 中层(共XX层)
3 中层(共XX层)
4 高层(共XX层)
Name: floors, dtype: object
使用str.findall()提取其中的数字
>>> data.str.findall(r'\d.').str.get(0)[:5]
0 16
1 31
2 33
3 33
4 28
Name: floors, dtype: object
使用str.extract()指定捕获组以直接提取数字
>>> data.str.extract(r'(\d.)',expand=False)[:5]
0 16
1 31
2 33
3 33
4 28
Name: floors, dtype: object
(6)对多个标签样本进行哑变量编码
使用str属性进行哑变量编码,并使用sep指定分隔符
>>> s = pd.Series(["Animation,Children's,Comedy","Comedy,Romance","Animation","Comedy"])
>>> s
0 Animation,Children's,Comedy
1 Comedy,Romance
2 Animation
3 Comedy
#对多个标签进行哑变量编码
>>> s.str.get_dummies(sep=',')
Animation Children's Comedy Romance
0 1 1 1 0
1 0 0 1 1
2 1 0 0 0
3 0 0 1 0