处理文本数据
该文章内容为《Pandas数据分析实战》的学习笔记
导入需要的包和数据
import pandas as pd
inspections = pd.read_csv("pandas-in-action-master/chapter_06_working_with_text_data/chicago_food_inspections.csv")
inspections.head()
字母的大小写和空格
我们可以观察到Name列存在两个问题:一个是大小写不一致,一个是值的前后包含空格
Series对象的str属性公开了一个StringMethods对象,这是一个用于处理字符串的强大工具,我们可以用该对象来处理字符串。
处理空格
我们可以使用strip
系列方法删除字符串中的空格
lstrip
方法删除字符串开头的空格
dessert = " cheesecake "
dessert.lstrip()
rstrip
方法删除字符串末尾的空格
dessert.rstrip()
strip
方法删除字符串两端的空格
dessert.strip()
接下来我们来处理数据
inspections["Name"] = inspections["Name"].str.strip()
这种方法只适合与列数较少的DataFrame,对于列数较多的DataFrame我们可以用循环来迭代
for column in inspections.columns:
inspections[column] = inspections[column].str.strip()
处理大小写
lower
方法将所有字符串中的字母转换为小写
inspections["Name"].str.lower()
upper
则是转换为大写
还可以使用str.capitalize
方法将Series中的每个字符串的首字母大写
inspections["Name"].str.capitalize()
str.title
将每个单词的第一个字母大写
inspections["Name"].str.title()
inspections["Name"] = inspections["Name"].str.title() # 存储
字符串切片
接下来我们要对风险类型这一列进行处理,假设我们要提取数字形式的风险类型,看似很简单。但总是存在各种出错的可能,比如:是否所有列都是一样的格式。我们可以通过调用unique
方法来找出答案
inspections["Risk"].unique()
我们可以看到这里还有其他格式的数据,这里我们要对All和nan进行处理。这里我们将All值替换为"Risk 4(Extreme)",删除NaN值
inspections = inspections.replace(to_replace="All", value = "Risk 4(Extreme)")
inspections = inspections.dropna(subset=["Risk"])
inspections["Risk"].unique()
字符串切片和字符替换
str.slice
方法可以用来按索引位置从字符串中提取子字符串。该方法接受其实索引和结束索引作为参数。下限(起点)是包含在内的,而上限(结束点)是不包含在内的
inspections["Risk"].str.slice(5, 6).head()
还可以使用Python的切片语法替换slice
方法
inspections["Risk"].str[5:6].head()
如果想要提取风险级别
inspections["Risk"].str.slice(8, -1).head()
也可以用正则表达式来进行更加复杂的限制,这个我们在后面会介绍
布尔型方法
contains
方法检查每个Series值中是否包含字符串。当Pandas在字符串中找到方法所设定的参数时,该方法返回True,反之返回False。但是这就有一个问题,就是区分大小写,这个匹配过程是严格的大小写区分的,所以我们需要先使用lower
方法全部转换为小写
has_pizza = inspections["Name"].str.lower().str.contains("pizza")
inspections[has_pizza]
使用str.startswith
可以特殊性的查找开头
start_with_tacos = (inspections["Name"].str.lower().str.startswith("tacos"))
inspections[start_with_tacos]
使用str.endswith
方法可以特殊性的查找末尾
ends_with_tacos = (inspections["Name"].str.lower().str.endswith("tacos"))
inspections[ends_with_tacos]
拆分字符串
customers = pd.read_csv("pandas-in-action-master/chapter_06_working_with_text_data/customers.csv")
customers.head()
现在我们要将顾客的姓名拆分为名和姓,这里我们可以使用str.split
方法,使用指定的分隔符来拆分字符串。该方法返回一个列表,该列表由拆分后的所有子字符串组成。
customers["Name"].str.split(" ").head()
通过查看每个列表的长度,我们可以看到有的被拆分成了多个部分。
customers["Name"].str.split(" ").str.len().head()
这里我们设置一个拆分数量的最大阈值1,这网Pandas只会在第一个空格出拆分字符串。str.get
可以根据每行的索引位置从列表中提取值,例如可以定位索引位置0,从而提取每个列表的第一个元素
customers["Name"].str.split(pat = " ", n = 1).str.get(0)
同时我们还可以将expand参数设定为True,这样该方法会返回一个新的DateFrame
customers[["First Name", "Last Name"]] = customers["Name"].str.split(pat = " ", n = 1, expand = True)
customers.head()
接下来删除原始的Name列
customers = customers.drop(labels = ["Name"], axis = "columns")
customers.head()
代码挑战
customers
数据集包括一个 Address
列,该列中的每个地址由街道、城市、州和邮政编码组成。
本节的挑战是将 Address
列中的这 4 个值拆开,将它们分配给新的 Street
、City
、State
和 Zip
列,然后删除 Address
列。首先自己尝试解决这个问题,然后再查看解决方案。
解决方案
customers.head()
customers[["Street", "City", "Strate", "Zip"]] = customers["Address"].str.split(pat = ",", expand = True)
customers.head()
customers = customers.drop(labels = ["Address"], axis = "columns")
customers.head()
关注公众号小辛到处学,发送1,获取文中的数据资源