这次文章的内容是pandas的文本数据
从 pandas 的 1.0.0 版本开始,引入了 string 类型,其引入的动机在于:原来所有的字符串类型都会以 object 类型的 Series 进行存储,但 object 类型只应当存储混合类型,例如同时存储浮点、字符串、字典、列表、自定义类型等,因此字符串有必要同数值型或 category 一样,具有自己的数据存储类型,从而引入了 string 类型。
首先,应当尽量保证每一个序列中的值都是字符串的情况下才使用 str 属性,但这并不是必须的,其必要条件是序列中至少有一个可迭代(Iterable)对象,包括但不限于字符串、字典、列表。对于一个可迭代对象, string 类型的 str 对象和 object 类型的 str 对象返回结果可能是不同的。
从下面的例子可以看出object类型和string对象的区别
s = pd.Series([{1: 'temp_1', 2: 'temp_2'}, ['a', 'b'], 0.5, 'my_string'])
print(s.str[1])
print()
print(s.astype('string').str[1])
out
0 temp_1
1 b
2 NaN
3 y
dtype: object
0 1
1 '
2 .
3 y
dtype: string
当为object类型是,则将数据看成可迭代对象,如果转为string对象,那么则将所有数据看成字符串,相当于在外面加了一层引号。所以我们可以看到索引值为1的数据,在object下取其索引为1返回temp,而在string的情况下则返回了一个'
,相当于把列表看成一整个字符串。
元字符基础
元字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
[ ] | 字符类,匹配方括号中包含的任意字符 |
[^ ] | 否定字符类,匹配方括号中不包含的任意字符 |
* | 匹配前面的子表达式零次或多次 |
+ | 匹配前面的子表达式一次或多次 |
? | 匹配前面的子表达式零次或一次 |
{n,m} | 花括号,匹配前面字符至少 n 次,但是不超过 m 次 |
(xyz) | 字符组,按照确切的顺序匹配字符xyz |
| | 分支结构,匹配符号之前的字符或后面的字符 |
\ | 转义符,它可以还原元字符原来的含义 |
^ | 匹配行的开始 |
$ | 匹配行的结束 |
简写字符集
简写 | 描述 |
---|---|
\w | 匹配所有字母、数字、下划线: [a-zA-Z0-9_] |
\W | 匹配非字母和数字的字符: [^\w] |
\d | 匹配数字: [0-9] |
\D | 匹配非数字: [^\d] |
\s | 匹配空格符: [\t\n\f\r\p{Z}] |
\S | 匹配非空格符: [^\s] |
\B | 匹配一组非空字符开头或结尾的位置,不代表具体字符 |
str.split
能够把字符串的列进行拆分,其中第一个参数为正则表达式,可选参数包括从左到右的最大拆分次数n
,是否展开为多个列expand
。
s = pd.Series(['上海市黄浦区方浜中路249号', '上海市宝山区密山路5号'])
s.str.split('[市区路]')
out
0 [上海, 黄浦, 方浜中, 249号]
1 [上海, 宝山, 密山, 5号]
dtype: object
关于合并一共有两个函数,分别是str.join
和str.cat
。str.join
表示用某个连接符把Series
中的字符串列表连接起来,如果列表中出现了非字符串元素则返回缺失值:
s = pd.Series([['a','b'], [1, 'a'], [['a', 'b'], 'c']])\
s.str.join('-')
out
0 a-b
1 NaN
2 NaN
dtype: object
str.cat
用于合并两个序列,主要参数为连接符sep
、连接形式join
以及缺失值替代符号na_rep
,其中连接形式默认为以索引为键的左连接。
s1 = pd.Series(['a','b'])
s2 = pd.Series(['cat','dog'])
s1.str.cat(s2,sep='-')
out
0 a-cat
1 b-dog
dtype: object
s2.index = [1, 2]
s1.str.cat(s2, sep='-', na_rep='?', join='outer')
out
0 a-?
1 b-cat
2 ?-dog
dtype: object
str.contains
返回了每个字符串是否包含正则模式的布尔序列:
s = pd.Series(['my cat', 'he is fat', 'railway station'])
s.str.contains('\s\wat')
out
0 True
1 True
2 False
dtype: bool
如果需要用正则表达式来检测开始或结束字符串的模式,可以使用str.match
,其返回了每个字符串起始处是否符合给定正则模式的布尔序列:
s.str.match('m|h')
out
0 True
1 True
2 False
dtype: bool
str.replace
和replace
并不是一个函数,在使用字符串替换时应当使用前者。
s.str.match('m|h')
out
0 True
1 True
2 False
dtype: bool
提取既可以认为是一种返回具体元素(而不是布尔值或元素对应的索引位置)的匹配操作,也可以认为是一种特殊的拆分操作。前面提到的str.split例子中会把分隔符去除,这并不是用户想要的效果,这时候就可以用str.extract进行提取:
pat = '(\w+市)(\w+区)(\w+路)(\d+号)'
s.str.extract(pat)
out
0 | 1 | 2 | 3 | |
---|---|---|---|---|
0 | 上海市 | 黄浦区 | 方浜中路 | 249号 |
1 | 上海市 | 宝山区 | 密山路 | 5号 |
2 | 北京市 | 昌平区 | 北农路 | 2号 |
通过子组的命名,可以直接对新生成DataFrame的列命名: |
pat = '(\w+市)(\w+区)(\w+路)(\d+号)'
s.str.extract(pat)
out
市名 | 区名 | 路名 | 编号 | |
---|---|---|---|---|
0 | 上海市 | 黄浦区 | 方浜中路 | 249号 |
1 | 上海市 | 宝山区 | 密山路 | 5号 |
2 | 北京市 | 昌平区 | 北农路 | 2号 |