pandas教程:String Manipulation 字符串处理和正则表达式re

本文主要是介绍pandas教程:String Manipulation 字符串处理和正则表达式re,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 7.3 String Manipulation(字符串处理)
  • 1 String Object Methods(字符串对象方法)
  • 2 Regular Expressions(正则表达式)
  • 3 Vectorized String Functions in pandas(pandas中的字符串向量化函数)

7.3 String Manipulation(字符串处理)

python很多内建方法很适合处理string。而且对于更复杂的模式,可以配合使用正则表达式。而pandas则混合了两种方式。

1 String Object Methods(字符串对象方法)

大部分string处理,使用内建的一些方法就足够了。比如,可以用split来分割用逗号区分的字符串:

val = 'a,b, guido'
val.split(',')
['a', 'b', ' guido']

split经常和strip一起搭配使用来去除空格(包括换行符):

pieces = [x.strip() for x in val.split(',')]
pieces
['a', 'b', 'guido']

可以使用+号把::和字符串连起来:

first, second, third = pieces
first + '::' + second + '::' + third
'a::b::guido'

但这种方法并不python,更快的方法是直接用join方法:

'::'.join(pieces)
'a::b::guido'

其他一些方法适合锁定子字符串位置相关的。用in关键字是检测substring最好的方法,当然,indexfind也能完成任务:

'guido' in val
True
val.index(',')
1
val.find(':')
-1

注意indexfind的区别。如果要找的string不存在的话,index会报错。而find会返回-1:

val.index(':')
---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-11-280f8b2856ce> in <module>()
----> 1 val.index(':')ValueError: substring not found

count会返回一个substring出现的次数:

val.count(',')
2

replace会取代一种出现方式(pattern)。也通常用于删除pattern,传入一个空字符串即可:

val.replace(',', '::')
'a::b:: guido'
val.replace(',', '')
'ab guido'

2 Regular Expressions(正则表达式)

正则表达式能让我们寻找更复杂的pattern。通常称一个表达式为regex,由正则表达语言来代表一个字符串模式。可以使用python内建的re模块来使用。

关于正则表达式,有很多教学资源,可以自己找几篇来学一些,这里不会介绍太多。

re模块有以下三个类别:patther matching(模式匹配), substitution(替换), splitting(分割)。通常这三种都是相关的,一个regex用来描述一种pattern,这样会有很多种用法。这里举个例子,假设我们想要根据空格(tabsspacesnewlines)来分割一个字符串。用于描述一个或多个空格的regex\s+:

import re
text = "foo    bar\t baz  \tqux"
re.split('\s+', text)
['foo', 'bar', 'baz', 'qux']

当调用re.split('\s+', text)的时候,正则表达式第一次被compile编译,并且split方法会被调用搜索text。我们可以自己编译regex,用re.compile,可以生成一个可以多次使用的regex object

regex = re.compile('\s+')
regex.split(text)
['foo', 'bar', 'baz', 'qux']

如果想要得到符合regex的所有结果,以一个list结果返回,可以使用findall方法:

regex.findall(text)
['    ', '\t ', '  \t']

为了防止\在正则表达式中的逃逸,推荐使用raw string literal,比如r'C:\x',而不是使用'C:\\x

使用re.compile创建一个regex object是被强烈推荐的,如果你打算把一个表达式用于很多string上的话,这样可以节省CPU的资源。

matchsearch,与findall关系紧密。不过findall会返回所有匹配的结果,而search只会返回第一次匹配的结果。更严格地说,match只匹配string开始的部分。这里举个例子说明,我们想要找到所有的邮件地址:

text = """Dave dave@google.com Steve steve@gmail.com Rob rob@gmail.com Ryan ryan@yahoo.com """pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
# re.IGNORECASE makes the regex case-insensitive 
regex = re.compile(pattern, flags=re.IGNORECASE)

使用findall找到一组邮件地址:

regex.findall(text)
['dave@google.com', 'steve@gmail.com', 'rob@gmail.com', 'ryan@yahoo.com']

search返回text中的第一个匹配结果。match object能告诉我们找到的结果在text中开始和结束的位置:

m = regex.search(text)
m
<_sre.SRE_Match object; span=(5, 20), match='dave@google.com'>
text[m.start():m.end()]
'dave@google.com'

regex.match返回None,因为它只会在pattern存在于strng开头的情况下才会返回匹配结果:

print(regex.match(text))
None

sub返回一个新的string,把pattern出现的地方替换为我们指定的string

print(regex.sub('REDACTED', text))
Dave REDACTED Steve REDACTED Rob REDACTED Ryan REDACTED 

假设你想要找到邮件地址,同时,想要把邮件地址分为三个部分,username, domain name, and domain suffix.(用户名,域名,域名后缀)。需要给每一个pattern加一个括号:

pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern, flags=re.IGNORECASE)

match object会返回一个tuple,包含多个pattern组份,通过groups方法:

m = regex.match('wesm@bright.net')
m.groups()
('wesm', 'bright', 'net')

findall会返回a list of tuples:

regex.findall(text)
[('dave', 'google', 'com'),('steve', 'gmail', 'com'),('rob', 'gmail', 'com'),('ryan', 'yahoo', 'com')]

sub也能访问groups的结果,不过要使用特殊符号 \1, \2。\1表示第一个匹配的group,\2表示第二个匹配的group,以此类推:

print(regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text))
Dave Username: dave, Domain: google, Suffix: com Steve Username: steve, Domain: gmail, Suffix: com Rob Username: rob, Domain: gmail, Suffix: com Ryan Username: ryan, Domain: yahoo, Suffix: com 

3 Vectorized String Functions in pandas(pandas中的字符串向量化函数)

一些复杂的数据清理中,string会有缺失值:

import numpy as np
import pandas as pd
data = {'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan}
data = pd.Series(data)
data
Dave     dave@google.com
Rob        rob@gmail.com
Steve    steve@gmail.com
Wes                  NaN
dtype: object
data.isnull()
Dave     False
Rob      False
Steve    False
Wes       True
dtype: bool

可以把一些字符串方法和正则表达式(用lambda或其他函数)用于每一个value上,通过data.map,但是这样会得到NA(null)值。为了解决这个问题,series有一些数组导向的方法可以用于字符串操作,来跳过NA值。这些方法可以通过seriesstr属性;比如,我们想检查每个电子邮箱地址是否有'gmail' with str.contains:

data.str
<pandas.core.strings.StringMethods at 0x111f305c0>
data.str.contains('gmail')
Dave     False
Rob       True
Steve     True
Wes        NaN
dtype: object

正则表达式也可以用,配合任意的re选项,比如IGNORECASE

pattern
'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})'
data.str.findall(pattern, flags=re.IGNORECASE)
Dave     [(dave, google, com)]
Rob        [(rob, gmail, com)]
Steve    [(steve, gmail, com)]
Wes                        NaN
dtype: object

有很多方法用于向量化。比如str.getindex索引到str属性:

matches = data.str.match(pattern, flags=re.IGNORECASE)
matches
/Users/xu/anaconda/envs/py35/lib/python3.5/site-packages/ipykernel/__main__.py:1: FutureWarning: In future versions of pandas, match will change to always return a bool indexer.if __name__ == '__main__':Dave     (dave, google, com)
Rob        (rob, gmail, com)
Steve    (steve, gmail, com)
Wes                      NaN
dtype: object

为了访问嵌套list里的元素,我们可以传入一个index给函数:

matches.str.get(1)
Dave     google
Rob       gmail
Steve     gmail
Wes         NaN
dtype: object
matches.str.get(0)
Dave      dave
Rob        rob
Steve    steve
Wes        NaN
dtype: object

也可以使用这个语法进行切片:

data.str[:5]
Dave     dave@
Rob      rob@g
Steve    steve
Wes        NaN
dtype: object

这篇关于pandas教程:String Manipulation 字符串处理和正则表达式re的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/366344

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3