章节编号是按照DataWhale的学习教程来的,不是按照我的笔记内容来的,所以你可能会发现从(四)分组直接跳到(八)文本数据了,这是正常的,因为中间我因为忙别的去了就断更了,现在想起来又懒得补了。
str
对象str
对象的设计意图str 对象是定义在
Index
或Series
上的属性,专门用于逐元素处理文本内容,其内部定义了大量方法,因此对一个序列进行文本处理,首先需要获取其str 对象。在Python 标准库中也有str 模块,为了使用上的便利,有许多函数的用法pandas照搬了它的设计。
>>>import pandas as pd
>>>import numpy as np
>>>s = pd.Series(['abcd', 'efg', 'hi'])
>>>s.str.upper()
Out[4]:
0 ABCD
1 EFG
2 HI
dtype: object
[]
索引器如同一般的字符串对象可以使用[]
切片索引,pandas的str
同样也可以。
>>>s.str[-1:0:-2]
Out[5]:
0 db
1 g
2 i
dtype: object
如果索引超出了范围,则返回NaN
。
>>>s.str[2]
Out[9]:
0 c
1 g
2 NaN
dtype: object
string
类型总体上说,绝大多数对于object 和string 类型的序列使用str 对象方法产生的结果是一致,但是在下面提到的两点上有较大差异:
首先,应当尽量保证每一个序列中的值都是字符串的情况下才使用str
属性,但这并不是必须的,其必要条件是序列中至少有一个可迭代(Iterable)对象,包括但不限于字符串、字典、列表。对于一个可迭代对象,string
类型的str
对象和object
类型的str
对象返回结果可能是不同的。
>>>s = pd.Series([{1: 'temp_1', 2: 'temp_2'}, ['a', 'b'], 0.5, 'my_string'])
>>>s
0 {1: 'temp_1', 2: 'temp_2'}
1 [a, b]
2 0.5
3 my_string
dtype: object
>>>s.str[1]
0 temp_1
1 b
2 NaN
3 y
dtype: object
>>>s_string=s.astype('str').astype('string')
>>>s_string.str[1]
0 1
1 '
2 .
3 y
dtype: string
可以看见,两种对象的返回值除了第3个都不一样。
这是因为object
类型的str
对象是对可迭代对象的元素进行[]
索引,如字典——根据key'1'
返回valuetemp_1
,列表——根据索引1
返回值b
,浮点数——不可迭代,返回缺失值NaN
,字符串——返回对应下标的字符'y'
。
而string
类型的str
对象是把整个元素转换成字面意义的字符串,即,甭管你啥类型啥符号,统统转成字符串,就连列表的方括号[]
、字典的花括号{}
、字符串的引号''
也都一并归入字符串了。
第二个区别:
表示查阅了资料也不知道什么是Nullable
类型,但确实发现了布尔类型似乎是有bool
和boolean
两种,这地方我确实不太懂,如果有懂的朋友可以在评论区指出,谢谢!
这一部分已在Python正则表达式笔记中详细介绍。但DataWhale教程中有一些笔误,在这里要提一下。
笔误一
这个地方应该是pattern
多输了一个\
。教程原意是匹配a?
或者a*
。
>>>import re
>>>text = 'aa?a*a'
>>>pattern_obj = re.compile(r'a\?|a\*')
>>>print(pattern_obj.findall(text))
['a?', 'a*']
但是硬要按'a\\?|a*'
来匹配的话,则是匹配a
或a\
或a*
,而且根据我的观察,好像是优先匹配|
前面的,不过我不太确定是否真的有这种规则,因为正则表达式我也是刚刚入门,如有误请大家指正。
>>>pattern_obj1 = re.compile(r'a\\?|a\*') # 优先匹配a或a\
>>>pattern_obj1.findall(text) # a*没被匹配到
['a', 'a', 'a', 'a']
>>>pattern_obj1 = re.compile(r'a\*|a\\?') # 优先匹配a*
>>>pattern_obj1.findall(text) # a*被匹配到了
['a', 'a', 'a*', 'a']
笔误二
这个在我的正则表达式笔记中已经说明了,\w
匹配的是所有字母、数字、下划线、汉字;同理,\W
是所有非字母、数字、下划线、汉字。
str.split 能够把字符串的列进行拆分,其中第一个参数为正则表达式,可选参数包括从左到右的最大拆分次数
n
,是否展开为多个列expand
。
>>>s = pd.Series(['上海市黄浦区方浜中路249 号','上海市宝山区密山路5 号'])
>>>s
0 上海市黄浦区方浜中路249 号
1 上海市宝山区密山路5 号
dtype: object
>>>s.str.split(r'[市区路]')
0 [上海, 黄浦, 方浜中, 249 号]
1 [上海, 宝山, 密山, 5 号]
dtype: object
>>>s.str.split(r'[市区路]',n=2,expand=True)
0 1 2
0 上海 黄浦 方浜中路249 号
1 上海 宝山 密山路5 号
关于合并,一共有两个函数,一个是Series.str.join
,还有一个是Series.str.cat
。
Series.str.join
join
是作用于单个Series
的,用于把Series
中的可迭代对象(列表/元组/字符串/集合)中的元素(必须是字符串)用指定符号连接起来,如果可迭代对象中冒出了非字符串(示例中1、2)或者根本就不是可迭代对象(示例中6),则返回缺失值。
>>>s = pd.Series([['a','b','c','d'], [1, 'a','b'], [['a', 'b'], 'c','d'],\
...: 'love',('a','e','i'),{'x','y','z'},1.3])
>>>s
0 [a, b, c, d]
1 [1, a, b]
2 [[a, b], c, d]
3 love
4 (a, e, i)
5 {x, y, z}
6 1.3
dtype: object
>>>s.str.join('-')
0 a-b-c-d
1 NaN
2 NaN
3 l-o-v-e
4 a-e-i
5 x-y-z
6 NaN
Series.str.cat
cat
作用于两个Series
,用于把这两个Series
中对应位置的字符串合并,不能出现非字符串对象,否则报错。
语法格式:Series.str.cat(others=None, sep=None, na_rep=None, join='left')
。其中,
others
可以是Series
, Index
, DataFrame
, np.ndarray
或 list-like
sep
指定合并时的分隔符na_rep
指定某Series
缺失值用何种符号显示,如果不指定该参数,则结果中也为缺失值join
指定连接方式,默认left
左连接,还可以是right
右连接/inner
内连接(取交集)/outer
外连接(取并集)。下面的例子可以看到不同连接方式的区别。>>>s1 = pd.Series(['a','b'])
>>>s2 = pd.Series(['cat','dog'], index=[1,2])
>>>s1
0 a
1 b
dtype: object
>>>s2
1 cat
2 dog
dtype: object
>>>s1.str.cat(s2,sep='-',na_rep='?',join='left') # 返回值的index与s1的相同
0 a-?
1 b-cat
dtype: object
>>>s1.str.cat(s2,join='right',sep='-',na_rep='?') # 返回值的index与s2的相同
1 b-cat
2 ?-dog
dtype: object
>>>s1.str.cat(s2,join='inner',sep='-',na_rep='?') # 返回值的index是s1和s2的index交集,故一定没有缺失值
1 b-cat
dtype: object
>>>s1.str.cat(s2,join='outer',sep='-',na_rep='?') # 返回值的index是s1和s2的index并集,故常常有缺失值
Series.str.contains
输入正则模式pat
,返回每个字符串是否包含正则模式的布尔序列;Series.str.startswith
和Series.str.match
相当于Series.str.contains
中pat=r'^'+r
,即匹配开头;Series.str.startswith
相当于Series.str.contains
中pat=r+r'$'
,即匹配结尾。
>>>s = pd.Series(['my cat', 'he is fat', 'railway station'])
>>>s.str.contains(r't$')
0 True
1 True
2 False
dtype: bool
>>>tmp = s.str[::-1]
>>>tmp
0 tac ym
1 taf si eh
2 noitats yawliar
dtype: object
>>>tmp.str.match(r'n|ta[fg]') # 匹配n或taf或tag
0 False
1 True
2 True
dtype: bool
除了上述返回值为布尔的匹配之外,还有一种返回索引的匹配函数,即
str.find
与str.rfind
,其分别返回从左到右和从右到左第一次匹配的位置的索引,未找到则返回-1
。需要注意的是这两个函数不支持正则匹配,只能用于字符子串的匹配。
>>>s = pd.Series(['This is an apple. That is not an apple.'])
>>>s.str.find('apple')
0 11
dtype: int64
在Pandas学习(二)—— Pandas基础我们已经学习了映射替换,在那里需要给replace
传入一个列表或字典,不足之处是无法使用正则表达式。对于str方法,可以使用正则表达式。