正则表达式判断是否包含指定字符串如何验证csv字符串是否有重复的值?

本篇内容为整理,博主使用代码为 Python3,部分内容和书本有出入。

在前几篇中我们介绍了 NumPy、pandas、matplotlib 三个库的基本操作,本篇介绍对数据的一些操作。

  • 数据规整化:清理、转换、合并、重塑

数据规整化:清理、转换、合并、重塑

  • pile自己编译一个regex,以得到一个可重用的regex对象,如上所示。如果打算对许多字符串应用同一条正则表达式,强烈建议通过这种方法,可以节省大量的 CPU 时间。

    得到匹配regex的所有模式:

    • findall:返回字符串中所有的匹配项。
    • search:只返回第一个匹配项。
    • match:只匹配字符串的首部。

    sub方法:将匹配到的模式替换为指定字符串,并返回所得到的新字符串。

    不仅想找出电子邮件地址,还想将各个地址分为 3 个部分,只需将待分段的模式的各部分用圆括号包起来:

    通过groups方法返回一个由模式各段组成的元组。


    对于带有分组功能的模式,findall会返回一个元组列表:

    sub还能通过诸如\1, \2之类的特殊符号访问各匹配项中的分组:

    为各个匹配分组加上一个名称,由这种正则表达式所产生的匹配对象可以得到一个简单易用的带有分组名称的字典:


    pandas 中矢量化的字符串函数


    通过data.map,所有字符串和正则表达式方法都能被应用于各个值,但如存在NA就会报错,为了解决这个问题,Series有一些能够跳过NA值的字符串操作方法,通过Seriesstr属性即可访问这些方法:

    实现矢量化的元素获取操作,对str.get/str属性上使用索引:

    对字符串进行子串截取:


    对数据集进行分组并对各组应用一个函数。

    在将数据集准备好之后,通常的任务就是计算分组统计生成透视表pandas提供了一个灵活高效的gruopby功能,对数据集进行切片、切块、摘要等操作。

    pythonpandas强大的表达能力可以执行复杂的多的分组运算:利用任何可以接受pandas对象或NumPy数组的函数。


    • 列表或数组,其长度与待分组的轴一样。
  • 字典或Series,给出待分组轴上的值与分组名之间的对应关系。
  • 函数,用于处理轴索引或索引中的各个标签。

变量grouped是一个GroupBy对象,它实际上还没有进行任何计算,只是含有一些有关分组键df['key1']的中间数据。

例如,调用GroupBymean方法来计算分组平均值:

Series根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。

通过两个键对数据进行了分组后,得到的Series具有一个层次化索引:

分组键可以是任何长度适当的数组:



GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)。

对于多重键,元组的第一个元素将会是由键值组成的元组。

对数据片段进行操作,如将这些数据片段做成一个字典:

groupby默认在axis=0上进行分组,通过设置可以在其它任何轴上进行分组,如可以根据dtype对列进行分组:



对于由DataFrame产生的GroupBy对象,用一个或一组(单个字符串或字符串数组)列名对其进行索引,就能实现选取部分列进行聚合的目的:

例如,对部分列进行聚合:计算data2列的平均值并以DataFrame形式得到结果:

返回一个已分组的DataFrame(传入的是列表或数组)或Series(传入的是标量形式的单个列名):


通过字典或 Series 进行分组


除数组以外,分组信息还可以其他形式存在

根据分组计算列的sum

Series作为分组键:

这里Series可以被看做一个固定大小的映射。pandas会检查Series以确保其索引根分组轴是对齐的。



任何被当做分组键的函数都会在各个索引值上被调用一次,其返回值就会被用作分组名称。

将函数根数组、列表、字典、Series混合使用(任何东西最终都会被转换为数组):

Key_list和人名对应,再在相同长度的对应一列里选min的值。



层次化索引数据集通过level关键字传入级别编号或名称:


可以使用经过优化的GroupBy的方法,还可以使用自己发明的聚合运算,还可以调用分组对象上已经定义好的任何方法,如 quantile可以计算SeriesDataFrame列的样本分位数:

GroupBy会高效地对Series进行切片,然后对各片调用piece.quantile(0.9),最后将这些结果组装成最终结果。

使用自己的聚合函数,传入aggregateagg方法即可:

有些方法如describe也可以用,但严格来讲它们并非聚合运算。


自定义聚合函数比表中的经过优化的函数慢得多,这是因为在构造中间分组数据块时存在非常大的开销(函数调用、数据重排等)。



传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名:

传入一个由(name, function )元组组成的列表,各元组的第一个元素会被用作DataFrame的列名:

对于DataFrame,定义一组应用于全部列的函数,或不同的列应用不同的函数。

传入带有自定义名称的元组列表:

对不同的列应用不同的函数:向agg传入一个从列名映射到函数的字典

只有将多个函数应用到至少一列时,DataFrame才会拥有层次化的列:


以“无索引”的形式返回聚合数据



聚合只是分组运算的其中一种,它接受能够将一维数据简化为标量值的函数。

接下来介绍 transformapply 方法,执行更多其他的分组运算。

为一个DataFrame添加一个用于存放各索引分组平均值的列:先聚合再合并。

transform会将一个函数应用到各个分组,然后将结果放置到适当的位置上。

检查demeaned现在的分组平均值是否为 0:

aggregate一样,transform也是一个有着严格条件的特殊函数,传入的函数只能产生两种结果,一个可以广播的标量值(如 np.mean) 或一个相同大小的结果数组。


apply:一般性的“拆分-应用-合并”


最一般化的GroupBy方法是applyapply会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各片段组合到一起。

根据分组选出最高的 5 个tip_pct值:编写一个函数,在指定列找出最大值,然后把这个值所在的行选取出来。

smoker分组并用该分组函数调用apply,得到:

top函数在DataFrame的各个片段上调用,然后结果由pandas.concat组装到一起,并以分组名称进行了标记。

最后结果就有了一个层次化索引,其内层索引值来自原DataFrame

如果传给apply的函数能够接受其他参数或关键字,可以将这些内容放在函数名后面一并传入:

GroupBy中,当调用如describe之类的方法时,实际上只是应用了下面两条代码的快捷方式:

除这些基本用法之外,能否充分发挥apply的威力很大程度上取决于你的创造力,传入的哪个函数能做什么全由你说了算,它只需返回一个pandas 对象标量值即可。



分组键会跟原始对象的索引共同构成结果对象中的层次化索引,将group_keys=False传入groupby即可禁止该效果:



pandas有一些能根据指定面元或样本分位数将数据拆分成多块的工具(cut 和 qcut),将这些函数跟groupby结合起来,就能非常轻松地实现对数据集的桶或分位数分析了。


“长度相等的桶”指的是“区间大小相等”,“大小相等的桶”指的是“数据点数量相等”。

利用cut将其装入长度相等的桶中:

cut返回的Factor对象可直接用于groupby,可以对data2做一些统计计算:

要根据样本分位数得到大小相等的桶,使用qcut

传入labels=False,即可只获取分位数的编号。否则那段还是区间而不是编号:


示例:用特定于分组的值填充缺失值


对于缺失数据的清理工作,有时用dropna将其滤除,有时则希望用一个固定值或由数据集本身所衍生出来的值去填充NA值,用fillna这个工具。

如用平均值去填充NA值

对不同的分组填充不同的值:将数据分组,并使用apply和一个能够对各数据块调用fillna的函数即可。

用这个分组平均值去填充NA值

也可以在代码中预定义各组的填充值,由于分组具有一个name 属性



从一个大数据集中随机抽取样本以进行蒙特卡罗模拟(Monte Carlo simulation)或其他分析工作。抽取的方式很多,其中的一些效率会比其他的高很多

一个办法是:选取np.random.permutation(N)的前K个元素,其中N为完整数据的大小,K为期望的样本大小。

从整副牌中抽出 5 张:

从每种花色中随机抽取两张牌,由于花色是牌名的最后一个字符,可以据此进行分组,并使用apply


示例:分组加权平均数和相关系数


例如对这个数据集利用category计算分组加权平均数:

计算一个由日收益率(通过百分数变化计算)与 SPX 之间的年度相关系数组成的DataFrame

计算列于列之间的相关系数:(苹果和微软的年度相关系数)


示例:面向分组的线性回归


按年计算 AAPL 对 SPX 收益率的线性回归:



是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。

在小费数据集中,根据daysmoker计算分组平均数(pivot_table 的默认聚合类型):

传入margins=True添加分项小计,将会添加标签为All的行和列,其值对应于单个等级中所有数据的分组统计。

这里All值为平均数。

要使用其他的聚合函数,将其传给aggfunc即可。例如使用countlen得到有关分组大小的交叉表:



是一种用于计算分组频率的特殊透视表。

crosstab的前两个参数可以是数组、Series、数组列表:

示例:2012联邦选举委员会数据库

抽取有关赞助人和赞助模式的统计信息。

通过unique,可以获取全部的候选人名单:

利用字典说明党派关系:

通过这个映射以及 Series对象的map方法,可以根据候选人姓名得到一组党派信息:

注意,该数据集既包括赞助也包括退款(负的出资额),为了简化分析过程,限定该数据集只能有正的出资额:

由于 Barack Obama 和 Mitt Romney 是最主要的两名候选人,专门准备了一个子集,只包含针对他们两人的竞选活动的赞助信息:

根据职业和雇主统计赞助信息

首先,根据职业计算出资总额:

这里只列出了前10个,注意到 许多职业都涉及相同的基本工作类型或同一样东西有多种变体,清理一些这样的数据:将一个职业信息映射到另一个。

对雇主信息也进行了同样的处理。

这里利用了dict.get,它允许没有映射关系的职业也能“通过”。

现在,可以通过pivot_table根据党派和职业对数据进行聚合,然后过滤掉总出资额不足 200 万美元对数据:

对 Obama 和 Romney 总出资额最高的职业和企业:先对候选人进行分组,然后求取最大值:

利用cut函数根据出资额的大小将数据离散化到多个面元中:

根据候选人姓名以及面元标签对数据进行分组:

对出资额求和并在面元内规格化,以便图形化显示两位候选人各种赞助额度的比例:

首先,根据候选人和州对数据进行聚合:

对各行除以总赞助额,就得到各候选人在各州的总赞助额比例:


}

RegexTester是一款正则表达式测试器,支持单行模式、多行模式,经典的窗口设计,该工具允许你测试和分析正则表达式。正则表达式通常用于两种任务:1.验证,2.搜索/替换。用于验证时,通常需要在前后分别加上^和$,以匹配整个待验证字符串;搜索/替换时是否加上此限定则根据搜索的要求而定

支持仅使用表达式里的选中部分进行匹配

支持树形和表格两种结果查看方式

选中树结点或单元格时自动选中源文本中对应的部分

表格内容可导出为csv文件(在表格模式下,右击结果,选择弹出菜单里的"导出(*.csv)")

支持拖入文件作为匹配源文本

支持快捷键操作(F5运行, F4切换查询替换模式, F6切换结果显示方式, F2复制代码, F8切换焦点)

支持生成并拷贝C#代码到系统剪切板

支持忽略大小写,单行模式,多行模式,忽略空白,显式匹配等多种选项

自动加载上次关闭前运行的最后一组数据

其中(?<=)为反向预搜索,表示要匹配的字符串前面必须是scr="

(?=)为正向预搜索,表示要匹配的字符串后面必须是"

.*?表示要匹配的部分

\b匹配单词的开始或结束
*表示重复0零次或多次
{n,} 重复n次或更多次
.表示除了换行符以外的任意字符
.*连在一起就意味着任意数量的不包含换行的字符
\d表示一位数字(0,或1,或2…或9)
\s表示任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格
\w匹配字母或数字或下划线或汉字
\表示转义,比如\"表示",\(表示(
[]表示范围,比如[.?!]匹配标点符号(.或?或!),[0-9]代表的含意与\d就是完全一致的:表示1位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)
|表示分支(或者),比如\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符
例子:\S+匹配不包含空白符的字符串。

}

如下,一些学生的考试成绩,我需要根据他们的名字来判断他们的性别, 然后存在一个新列里头。

在我实际的工作中,“通过名字来判断性别”这件事我必须要用正则表达式来完成。

       DataFrame中有一种很有效的过滤方式是df[bool exp],其中的bool exp为布尔表达式,可以是关于df的任何可以产生布尔值的运算或判断,并且还可以是多个布尔表达式的逻辑运算用括号分隔。

df['name']得到的就是一个Series。所以直接套用就好咯。

}

我要回帖

更多关于 正则表达式判断是否包含指定字符串 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信