4-Pandas数据预处理之数据转换(文本数据规整)
说明:本片博文接上篇博文【Pandas数据预处理之数据转换(哑变量编码pd.get_dummies())】以及上上篇博文【 Pandas数据预处理之数据转换(df.map()、df.replace())】
Pandas对于字符串和文本处理通常是由一些内置的字符串方法指定,一般语法格式为: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
若需要将分隔开的元素规整成一个DataFrame,可以使用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