Python的一个使用优势是它在处理和操作字符串数据方面相对容易。
在此基础上Pandas提供了一套全面的向量化字符串操作(vectorized string operation),这些操作成为处理现实世界数据时所需的必不可少的功能。
在本文中,我们将介绍一些Pandas的字符串操作,然后学习如何使用它们来部分清理从互联网上收集的一个杂乱无章的食谱数据集进行局部清洗。
Pandas字符串操作介绍
我们在前面的章节中看到了像NumPy和Pandas这样的工具是如何将算术运算泛化的,这样我们就可以轻松快速地对多个数组元素进行相同的运算。例如
这种向量化操作简化了对数据数组的操作语法:我们不再需要担心数组的长度或维度,而只需要担心我们所需要的操作。
然而,对于字符串数组,NumPy并没有提供这样简单的接口访问方式。所以我们只能使用比较占内存的for循环语法来解决问题。
这也许足以有效应付一些数据,但如果数据中有任何缺失的值,那这样就会引起异常。例如:
Pandas的str属性堪称两全其美的方法。
它既可以做向量化的字符串操作的需求,也可以处理好缺失的数据。举个例子,假设我们用这个数据创建一个Pandas Series:
现在我们可以调用转换大写方法capitalize( ),将所有字符串变成大写,同时跳过缺失值:
在这个str属性上使用(基础文章有概括如何使用tab键查看python方法),将列出所有Pandas可用的向量化字符串方法。
Pandas字符串方法列表
如果你对Python中的字符串操作很熟悉的话,那么就会发现Pandas绝大多数的字符串语法都是足够直观的,甚至可以列出一个可用的表格。从这里开始,我们将使用以下一系列名称来演示:
几乎所有Python内置的字符串方法都被复制到Pandas的向量化字符串方法中。下面是一个Pandas的str方法镜像Python字符串方法的列表:
需要注意的是,这些函数有不同的返回值,比如 lower( ) 方法返回一个字符串Series:
但还有些方法来返回数值:
有些方法可以返回布尔值:
还有一些则返回每个元素的列表或其他复合值的方法:
我们将在接下来的讨论中,进一步来学习这类由列表元素构成的Series (series-of-lists)对象。
此外,还有一些支持正则表达式的方法可以用来处理每个字符串元素。下面表中内容是Pandas向量化字符串方法根据并遵循 Python标准库的re模块函数实现的API。
有了这些方法,你就可以进行各种有趣的操作了。例如,我们可以通过提取每个元素的前面的一组连续的字符来作为每个人的名字(first name):
我们也可以实现一些更复杂的操作,比如找到所有以辅音开头和结尾的名字——这可以利用字符串开始符号(^)和字符串结尾符号($)的正则表达式字符来实现:
能够将正则表达式应用到Series与DataFrame之中的话,就有可能实现更多的数据分析和清洗方法。
还有其他一些方法也可以实现方便的操作,如下表所列:
向量化字符串的取值与切片操作。
需要特别指出的是,get( )和slice( )操作可以实现从每个字符串数组中获取向量化元素。例如,我们可以使用str.slice(0, 3)来获取每个字符串数组的前三个字符。通过Python的标准取值方法也可以取得同样的效果,例如,
df.str.slice(0,3)等价于df.str[0:3]:
通过df.str.get(i)和df.str[i]进行索引也有同样类似的效果。
get( )和slice( )的操作还可以让你在split( )操作之后使用。例如,要提取每个名字的姓,我们可以结合使用split( )和get( ):
2. 指标变量
另一个需要多花点时间额外解释的是get_dummies()方法。当你的数据中有一列包含了某种已被编码的指标(coded indicator)时,这个方法就派上用处了。例如,我们有一个数据集,其中包含了某种编码信息的数据集,如A=”出生在美国”,B=”出生在英国”,C=”喜欢奶酪”,D=”喜欢垃圾邮件”:
get_dummies( )方法可以让你快速将这些指标变量拆分到DataFrame中。
通过Pandas自带的这些字符串操作方法,你可以建立一个功能强大的字符串处理程序来清理数据了。
食谱数据库的案例
前面介绍的这些向量化字符串操作方法,在清理混乱的现实数据的过程中变得非常有用。
下面我将通过一个从网络上获取的公开食谱数据库例子进行讲解。
我们的目标将是把这些食谱数据解析成配料表,这样我们就可以根据我们手头的一些配料来快速找到一个食谱了。
获取数据的原文件可以在 上找到,当前最新版本的数据库链接也可以在那里找到。
截至2016年春季,这个数据库大约有30MB,可以用这些命令下载并解压:
这个数据库是JSON格式的,所以我们将尝试通过 pd.read_json 来读取数据:
我们竟然得到了一个提示数据里有”trailing data”(数据断行)的ValueError错误。
在CSDN上搜索这个错误的含义,知道原因是由于使用了一个文件,其中每一行本身就是一个有效的JSON对象,但完整的文件却不是这样的。我们来看看这个解释是否属实:
显然每一行都是一个有效的JSON,所以我们需要将这些字符串连接起来。我们可以做到这一点的一种方法是构建一个包含所有这些JSON条目的字符串表示,然后再用 pd.read_json 来读取所有数据:
我们看到有近20万个菜谱,还有17列。我们来抽一行看看具体内容:
这里有很多信息,而且其中很多信息都是以一种非常混乱的形式存在,这是从网络上抓取的典型数据。
尤其是配料表是字符串格式的,我们要仔细提取我们感兴趣的信息。
我们先来仔细看看配料表:
食材表平均长250个字符,最短的字符串为0,最长的竟然有近万个字符!
出于好奇,我们来看看哪种配方的配料表最长:
这看起来肯定是一个绝对复杂的食谱。
我们还可以再做一些其他的探索;比如,我们看看有多少食谱是早餐类的:
或者说有多少食谱把肉桂(cinnamon)列为原料:
我们甚至可以看看是否有食谱将原料拼错为 “cinamon”:
这是用Pandas字符串工具可以实现的基本数据探索类型。Python非常适合进行类似的数据清理工作。
制作简单的美食推荐系统
让我们更进一步,开始研究一个简单的菜谱推荐系统:给定一个食材清单,系统会推荐使用了所有这些食材的菜谱。
虽然概念上很简单,但由于大量不规则数据(heterogeneity)的存在,这个任务变得很复杂:例如,并没有一个简单直接的操作,可以从每一行中提取一个干净的食材列表。
因此,我们在这里简单处理一下:
首先,我们将从一个常见的成分列表开始,通过简单搜索,来看看它们是否在每个食谱的成分列表中。
为了简单起见,我们暂且只说香料和调味料:
然后,我们可以建立一个由True和False值组成的布尔类型 DataFrame,来判断这个原料是否出现在食谱列表中:
现在,举个例子,假设我们想找到一个使用欧芹parsley、辣椒粉paprika和龙蒿tarragon这三种食材的食谱。
我们可以使用DataFrames的query( )方法来快速地计算出来。
我们只找到了10个同时包含这个组合的菜谱,我们用这个选择返回的索引来发现含有这个组合的菜谱名称:
现在python字符串查找,我们已经将食谱选择范围缩小到了原来近2万份食谱的两千分之一了,这样就可以更明智地决定我们中意的食谱了。
2. 继续完善美食推荐系统
希望这个例子能让你对Pandas字符串方法可以高效解决哪些数据清问题有个初步概念。
当然,如果要建立一个非常强大稳定的菜谱推荐系统,还需要更多大量的工作!
从每个食谱中提取完整的配料表,将是一个这个任务的重中之重。
不过,由于使用的格式种类繁多,解析它们将是一个相对耗时的过程。
这也说明在数据分析中python字符串查找,对真实世界数据的清洗和整理工作往往会占据大部分的工作时间,而Pandas提供的工具可以帮助你高效地完成这项工作。
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688