本系列文章配套代码获取有以下三种途径:
-
可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):
https://returu.github.io/Python_Data_Analysis/lab/index.html
-
也可以通过百度网盘获取,需要在本地配置代码运行环境,环境配置可以查看【Python基础】2.搭建Python开发环境:
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj
提取码:mnsj
-
前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis
根据《Python for Data Analysis 3rd Edition》翻译整理
—————————————————–
Pandas允许你将字符串和正则表达式简洁地应用到整个数组上,此外还能处理数据缺失带来的困扰。
1.Python内建字符串方法:
在许多字符串处理和脚本应用中,Python内建的字符串方法就足够了。例如,可以使用 split
将由逗号分隔的字符串拆分成几部分。
1>>> val = "a,b, cdef"
2
3>>> val.split(",")
4['a', 'b', ' cdef']
split
通常与 strip
结合使用以清除空格(包括换行符)。
1>>> pieces = [x.strip() for x in val.split(",")]
2>>> pieces
3['a', 'b', 'cdef']
这些子字符串可以使用加法与双冒号分隔符连接在一起。
1>>> first, second, third = pieces
2>>> first + "::" + second + "::" + third
3'a::b::cdef'
但这不是实用的通用方法。一种更快、更 Pythonic 的方法是,将列表或元组传递给字符串“::”的 join
方法
1>>> "::".join(pieces)
2'a::b::cdef'
其他方法与定位子字符串有关。使用 Python 的 in
关键字是检测子字符串的最佳方法,尽管index
和 find
也能实现同样功能。
请注意,find和 index
之间的区别在于,如果未找到字符串,则 index
会引发异常,而find会返回 –1。
1>>> "a" in val
2True
3
4>>> val.index(",")
51
6
7>>> val.find(":")
8-1
9
10>>> val.index(":")
11ValueError: substring not found
相关地, count
返回某个特定子字符串在字符串中出现的次数。
1>>> val.count(",")
22
replace
会将一种模式替换为另一种模式。它也常用于通过传递一个空字符串来删除某个模式。
1>>> val.replace(",", "::")
2'a::b:: cdef'
3>>> val.replace(",", "")
4'ab cdef'
Python 内建的字符串方法如下所示:
方法 |
说明 |
count | 返回子串在字符串中非重叠出现的次数 |
endswith |
如果字符串以后缀结尾则返回 True |
startswith | 如果字符串以前缀开头,则返回 True |
join | 使用字符串作为分隔符来连接一系列其他字符串 |
index | 如果在字符串中找到,则返回第一次出现的传递子字符串的起始索引;如果未找到则引发 ValueError |
find | 返回子字符串在字符串中第一次出现的第一个字符的位置;类似于index,但如果未找到则返回 –1 |
rfind | 返回子字符串在字符串中最后一次传时第一个字符的位置;如果未找到,则返回 –1 |
replace | 用一个字符串替换另一个字符串 |
strip, rstrip, lstrip | 修剪空白,分别包括两侧、右侧或左侧的换行符 |
split | 使用传递的分隔符将字符串分解为子字符串列表 |
lower | 将字母字符转换为小写 |
upper | 将字母字符转换为大写 |
casefold | 将字符转换为小写,并将任何特定于区域的变量字符串组合转换为常见的可比较形式 |
ljust, rjust | 左对齐或右对齐;用空格(或其他一些填充字符)填充字符串的另一侧以返回具有最小宽度的字符串 |
正则表达式提供了一种灵活的方式来搜索或匹配文本中的(通常更复杂的)字符串的模式。单个表达式,通常称为regex,是根据正则表达式语言形成的字符串。Python 内置的 re
模块负责将正则表达式应用于字符串。
re
模块分为三个主题:模式匹配、替换和拆分。当然,这些都是相关的。
一个正则表达式描述了在文本中定位的一种模式,然后可以将其用于多种目标。
让我们看一个简单的例子:假设我们想用可变数量的空白字符(制表符、空格和换行符)拆分一个字符串,描述一个或多个空白字符的正则表达式是 s+
(为了在正则表达式中避免转义符 的影响,可以使用原生字符串语法,比如
r"C:x"
,而不是 "C:\x"
)。
1>>> import re
2
3>>> text = "foo bart baz tqux"
4>>> re.split(r"s+",text)
5['foo', 'bar', 'baz', 'qux']
当你调用 re.split(r"s+", text)
时,正则表达式首先会被编译,然后正则表达式的split
方法在传入的文本上被调用。你可以使用 re.compile
自己编译正则表达式,形成一个可重用的正则表达式对象(如果你打算将相同的表达式应用于多个字符串,强烈建议使用 re.compile
创建一个正则表达式对象,这样做将节省 CPU 周期)。
1>>> regex = re.compile(r"s+")
2
3>>> regex.split(text)
4['foo', 'bar', 'baz', 'qux']
相反,如果想获得与正则表达式匹配的所有模式的列表,则可以使用 findall方法。
1>>> regex.findall(text)
2[' ', 't ', ' t']
match
和 search与 findall密切相关。findall返回字符串中的所有匹配项,而 search仅返回第一个匹配项。match
更严格地,只在字符串的起始位置进行匹配。
例如,下面的一段文本和一个能够识别大多数电子邮件地址的正则表达式
1>>> text = """Dave dave@google.com
2Steve steve@gmail.com
3Rob rob@gmail.com
4Ryan ryan@yahoo.com"""
5
6>>> pattern = r"[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}"
7
8# re.IGNORECASE使正则表达式不区分大小写
9>>> regex = re.compile(pattern , flags=re.IGNORECASE)
在文本上使用 findall
方法会生成一个电子邮件地址列表。
1>>> regex.findall(text)
2['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com']
search
返回文本中第一个匹配到的电子邮件地址。对于前面提到的正则表达式,匹配对象只能告诉我们模式在字符串中的开始和结束位置。
1>>> m = regex.search(text)
2>>> m
3<re.Match object; span=(5, 20), match='dave@google.com'>
4>>> text[m.start():m.end()]
5'dave@google.com'
regex.match 返回 None,因为只有当模式出现在字符串的开头时它才会匹配。
1>>> print(regex.match(text))
2None
相关地,sub 将返回一个新字符串,原字符串中的模式会被新字符串替换。
1>>> print(regex.sub("REDACTED", text))
2Dave REDACTED
3Steve REDACTED
4Rob REDACTED
5Ryan REDACTED
假设你要查找电子邮件地址并同时将每个地址分成三个部分:用户名、域名和域名后缀。需要在要分割的模式部分周围加上括号。此时使用findall
将返回一个元组列表。
1>>> pattern = r"([A-Z0-9._%+-]+)@([A-Z0-9.-]+).([A-Z]{2,4})"
2>>> regex = re.compile(pattern, flags=re.IGNORECASE)
3>>> regex.findall(text)
4[('dave', 'google', 'com'),
5 ('steve', 'gmail', 'com'),
6 ('rob', 'gmail', 'com'),
7 ('ryan', 'yahoo', 'com')]
上面这个修改后的正则表达式生成的匹配对象的 groups
方法返回模式组件的元组。
1>>> m = regex.match("wesm@bright.net")
2>>> m.groups()
3('wesm', 'bright', 'net')
sub
也可以使用特殊符号,如1
和2
,访问每个匹配对象中的分组。符号1代表的是第一个匹配分组,符号2代表的是第二个匹配分组,以此类推。
1>>> print(regex.sub(r"Username: 1, Domain: 2, Suffix: 3", text))
2Dave Username: dave, Domain: google, Suffix: com
3Steve Username: steve, Domain: gmail, Suffix: com
4Rob Username: rob, Domain: gmail, Suffix: com
5Ryan Username: ryan, Domain: yahoo, Suffix: com
正则表达式方法如下所示:
方法 |
说明 |
findall | 将字符串中所有不重叠的匹配模式以列表形式返回 |
finditer | 与findall类似,但是返回的是迭代器 |
match | 在字符串的起始位置匹配模式,并可选择将模式组件匹配到分组中;如果模式匹配,则返回匹配对象,否则返回 None |
search | 扫描字符串的匹配模式,如果扫描到则返回匹配对象;与match不同,匹配可以在字符串中的任何位置,而不是仅在起始位置 |
split | 根据模式,将字符串拆分为多个部分 |
sub, subn | 用替换表达式替换字符串中所有的匹配 (sub) 或第 n 次出现的匹配串 (subn);使用符号1, 2, …来引用替换字符串中的匹配组元素 |
本篇文章来源于微信公众号: 码农设计师