本系列文章配套代码获取有以下三种途径:
-
可以在以下网站查看,该网站是使用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》翻译整理
—————————————————–
清理混乱的数据集以进行分析通常需要大量的字符串操作。更复杂的是,包含字符串的列有时会丢失数据:
1>>> data = {'name':['Dave','Steve','Rob','Wes'],
2... 'email':['dave@google.com','steve@gmail.com','rob@gmail.com',np.nan],
3... 'country':['Canada','France','Italy','USA']}
4
5>>> data = pd.DataFrame(data)
6>>> data
7 name email country
80 Dave dave@google.com Canada
91 Steve steve@gmail.com France
102 Rob rob@gmail.com Italy
113 Wes NaN USA
12
13>>> data.isna()
14 name email country
150 False False False
161 False False False
172 False False False
183 False True False
可以使用 data.map 将字符串和正则表达式方法(以 lambda 或其他函数传递)应用于每个值,但它会在 NA (null) 值上失败。为了解决这个问题,Series 为字符串操作提供了面向数组的方法,可以跳过并传播 NA 值。这些是通过 Series 的 str
属性访问的。
例如,我们可以使用 str.contains 检查每个电子邮件地址是否包含“gmail”:
1>>> data["email"].str.contains("gmail")
20 False
31 True
42 True
53 NaN
6Name: email, dtype: object
请注意,此操作的结果具有object
数据类型。Pandas 具有扩展类型(extension types),可以专门处理字符串、整数和布尔数据,直到最近,在处理缺失数据时还有些粗糙:
1>>> data_as_string_ext = data["email"].astype('string')
2>>> data_as_string_ext
30 dave@google.com
41 steve@gmail.com
52 rob@gmail.com
63 <NA>
7Name: email, dtype: string
8
9>>> data_as_string_ext.str.contains("gmail")
100 False
111 True
122 True
133 <NA>
14Name: email, dtype: boolean
正则表达式也可以结合任意 re 模块选项使用,例如 IGNORECASE。
1>>> pattern = r"([A-Z0-9._%+-]+)@([A-Z0-9.-]+).([A-Z]{2,4})"
2>>> data["email"].str.findall(pattern, flags=re.IGNORECASE)
30 [(dave, google, com)]
41 [(steve, gmail, com)]
52 [(rob, gmail, com)]
63 NaN
7Name: email, dtype: object
有几种方法可以进行向量化的元素检索,可以使用str.get或在str属性内部索引。
1>>> matches = data["email"].str.findall(pattern, flags=re.IGNORECASE).str[0]
2>>> matches
30 (dave, google, com)
41 (steve, gmail, com)
52 (rob, gmail, com)
63 NaN
7Name: email, dtype: object
8
9>>> matches.str.get(1)
100 google
111 gmail
122 gmail
133 NaN
14Name: email, dtype: object
也可以使用以下语法对字符串进行向量化的切片。
1>>> data["email"].str[:5]
20 dave@
31 steve
42 rob@g
53 NaN
6Name: email, dtype: object
str.extract
方法将捕获的正则表达式组作为 DataFrame 返回。
1>>> data["email"].str.extract(pattern, flags=re.IGNORECASE)
2 0 1 2
30 dave google com
41 steve gmail com
52 rob gmail com
63 NaN NaN NaN
Series 字符串方法的部分列表如下所示:
方法 |
说明 |
cat | 根据可选的分隔符按元素黏合字符串 |
contains | 返回是否含有某个模式/正则表达式的布尔值数组 |
count | 模式出现次数的计数 |
extract | 使用正则表达式从字符串Series中分组抽取一个或多个字符串,返回的结果是每个分组形成一列的DataFrame |
endswith | 等价于对每个元素使用x.endswith(pattern) |
startswith | 等价于对每个元素使用x.startswith(pattern) |
findall | 找出字符串中所有的模式/正则表达式匹配项,以列表形式返回 |
get | 对每个元素进行索引(获得第i个元素) |
isalnum | 等价于内建的str.alnum |
isalpha | 等价于内建的str.isalpha |
isdecimal | 等价于内建的str.isdecimal |
isdigit | 等价于内建的str.isdigit |
islower | 等价于内建的str.islower |
isnumeric | 等价于内建的str.isnumeric |
isupper | 等价于内建的str.isupper |
join | 根据传递的分隔符,将Series中的字符串联合 |
len | 计算每个字符串的长度 |
lower, upper | 转换大小写,等价于对每个元素进行x.lower() 或x.upper() |
match | 使用re.match将正则表达式应用到每个元素上,将匹配分组以列表形式返回 |
pad | 将空白加到字符串的左边、右边或两边 |
center | 等价于pad(side=”both”) |
repeat | 重复值(例如,s.str.repeat(3)相当于每个字符串的 x * 3) |
replace | 以其他字符串替代模式/正则表达式的匹配项 |
slice | 对Series中的字符串进行切片 |
split | 以分隔符或正则表达式对字符串进行拆分 |
strip | 对字符串两侧的空白进行消除、包括换行符 |
rstrip | 消除字符串右边的空白 |
lstrip | 消除字符串左边的空白 |
本篇文章来源于微信公众号: 码农设计师