【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)

文章目录

  • 1 字符串的常用方法
    • 表:字符串的常用方法
    • `String[start:end:step]`
    • String.replace & String.slice_replace
    • String.split
    • sep.join
    • String.strip/rstrip/lstrip
    • String.count
    • String.repeat
    • String.index & String.find
    • String.findall
    • String.extract/extractall
    • String.get
    • String.startswith/endswith
    • String.cat
    • String.contains
    • String.len
    • String.upper/lower
    • String.pad+side参数/center
  • 2 正则表达式
    • 2.1 匹配查询函数
    • 2.2 匹配替换函数
    • 2.3 匹配分割函数
    • 2.4 实际应用
  • 3 实战应用


1 字符串的常用方法

首先介绍一下Python中的字符串有哪些构造方法:
【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第1张图片
构造字符串可以使用三种形式的引号。

  • 如果字符串的内容不包含任何引号,那么单引号、双引号和三引号都可以使用;
  • 如果字符串的内容仅包含双引号,类似变量string1的形式,那么只能使用单引号或三引号构造字符串;
  • 如果字符串的内容仅包含单引号,类似变量string2的形 式,那么只能使用双引号或三引号完成字符串的创建;
  • 如果字符串的内容既包含单引号,又包含双引号,类似变量string3所示,那只能使用三 引号构建字符串。

所以,三引号是适用情况最多的字符串构造方法,而且三引号允许长字符串的换行,这是其他两种引号无法实现的,如变量 string4所示。

表:字符串的常用方法

方法 使用说明 方法 使用说明
String[start:end:step] 字符串切片 String.find 返回字符串首次出现的位置(找不到返回-1)
String.replace 字符串替换(文本/正则) String.findall 利用正则表达式,去字符串中匹配,返回查找结果的列表
String.slice_replace 使用给定的字符串,替换指定的位置的字符 String.extract/extractall 接受正则表达式,抽取匹配的字符串(一定要加上括号)
String.split 字符串分割(+expand/+join) String.get 获取指定位置的字符串
sep.join 将可迭代对象按sep分隔符拼接为字符串 String.startswith/endswith 判断某个字符串是否以…开头/结尾
String.strip/rstrip/lstrip 删除字符串首尾/右侧/左侧空白 String.cat 用于字符串的拼接
String.count 计算给定字符在字符串中出现的次数 String.contains 判断某个字符串是否包含给定字符
String.repeat 重复字符串几次 String.len 计算字符串长度
String.index 返回字符串首次出现的位置 String.upper/lower 英文大小写转换
String.pad+side参数/center 在字符串的左边、右边或左右两边添加给定字符

String[start:end:step]

df['身份证'].str[6:14]

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第2张图片

String.replace & String.slice_replace

# 替换:为_
df['身高'].str.replace(':','_')

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第3张图片

# 将手机号中的中间四位替换为四颗星
df['电话号码'].str.slice_replace(4,8,'****')

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第4张图片

  • replace中传入正则表达式,才叫好用;
  • 先不要管下面这个案例有没有用,你只需要知道,使用正则做数据清洗多好用;
df["收入"].str.replace("\d+\.\d+","正则")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第5张图片

String.split

# 普通用法
df['身高'].str.split(':')

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第6张图片

# split方法,搭配expand参数
df[['身高描述','final身高']]=df['身高'].str.split(':',expand=True)
df

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第7张图片

# split方法搭配join方法
df["身高"].str.split(":").str.join("?"*5)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第8张图片

sep.join

'-'.join('Python')

‘P-y-t-h-o-n’

'-'.join(df['姓名'])

在这里插入图片描述

String.strip/rstrip/lstrip

# 删除"  今天星期日  "的首尾空白
print("  今天星期日  ".strip())

# 删除"  今天星期日  "的左边空白
print("  今天星期日  ".lstrip())

# 删除"  今天星期日  "的右边空白
print("  今天星期日  ".rstrip())

今天星期日今天星期日今天星期日

String.count

df["电话号码"].str.count("3")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第9张图片

String.repeat

df['性别'].repeat(3)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第10张图片

df["性别"].str.repeat(3)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第11张图片

String.index & String.find

# 查询"Python"单词所在的位置
string6 = '我是一名Python用户,Python给我的工作带来了很多便捷。'
print(string6.index('Python'))
print(string6.find('Python'))

4
4


需要说明的是,字符串的index和find方法都是只能返回首次发现子串的位置,如果子串在原字符串中没有找到,对于index方法来说,则返回报错信息,对于find方法,则返回值-1。所以,推荐使用find方法寻找子串的位置,因为即使找不到子串也不会因为错误而影响其他程序的正常执行。


String.findall

findall使用正则表达式,做数据清洗,真的很香!

df["身高"].str.findall("[a-zA-Z]+")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第12张图片

String.extract/extractall

df["身高"].str.extract("([a-zA-Z]+)")

在这里插入图片描述

# extractall提取得到复合索引
df["身高"].str.extractall("([a-zA-Z]+)")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第13张图片

# extract搭配expand参数
df["身高"].str.extract("([a-zA-Z]+).*?([a-zA-Z]+)",expand=True)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第14张图片

String.get

df["姓名"].str.get(-1)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第15张图片

df["身高"].str.split(":").str.get(0)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第16张图片

String.startswith/endswith

df['姓名'].str.startswith('黄')

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第17张图片

df["英文名"].str.endswith("e")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第18张图片

String.cat

df["姓名"].str.cat(df["家庭住址"],sep='-'*3)

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第19张图片

String.contains

df["家庭住址"].str.contains("广")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第20张图片

String.len

df["家庭住址"].str.len()

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第21张图片

String.upper/lower

df['英文名'].str.upper()

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第22张图片

df['英文名'].str.lower()

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第23张图片

String.pad+side参数/center

df["家庭住址"].str.pad(10,fillchar="*") 
# 相当于ljust()

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第24张图片

df["家庭住址"].str.pad(10,side="right",fillchar="*") 
# 相当于rjust()

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第25张图片

df["家庭住址"].str.center(10,fillchar="*")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第26张图片

有时,光靠字符串的这些“方法”无法实现字符串的其他处理功能,例如,怎样在字符串中找到有规律的目标值、怎样替换那些不是固定值的目标内容、怎样按照多个分隔符将字符串进行切割等。关于这方面问题的解决,需要用到字符串的正则表达式,接下来我们就进入正则表达式的学习。

2 正则表达式

本节主要使用正则表达式完成字符串的查询匹配、替换匹配和分割匹配。在进入字符串的匹配之前,先来了解一下都有哪些常用的正则符号。

表:常用的正则符号
【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第27张图片

代表的是任意字符;
* 代表的是取 0 至 无限长度;
?代表的是非贪婪模式。
三个链接在一起是取尽量少的任意字符,一般不会这么单独写。
用法:他大多用在:.*?a
解释:就是取前面任意长度的字符,到底一个 a 出现,匹配如下q@wer_qwerqweraljlkjlkjlkj,得到:q@wer_qwerqwera这部分,如果匹配不到后面的 a 字符,则匹配为空。

如果读者能够比较熟练地掌握上表中的内容,相信在字符串处理过程中将会游刃有余。

如前文所说,本节将基于正则表达式完成字符串的查询、替换和分割操作,这些操作都需要导入re模块,并使用如下几个函数。

2.1 匹配查询函数

findall(pattern, string, flags=0)

findall函数可以对指定的字符串进行遍历匹配,获取字符串中所有匹配的子串,并返回一个列表结果。

  • pattern:指定需要匹配的正则表达式
  • string:指定待处理的字符串
  • flags:指定匹配模式,常用的值可以是re.I、re.M、re.S和re.X
    • re.I的模式——让正则表达式对大小写不敏感;
    • re.M的模式——让正则表达式可以多行匹配;
    • re.S的模式——指明正则符号.可以匹配任意字符,包括换行符\n;
    • re.X模式——允许正则表达式可以写得更加详细,如多行表示、忽略空白字符、加入注释等

2.2 匹配替换函数

sub(pattern, repl, string, count=0, flags=0)

sub函数的功能是替换,类似于字符串的replace方法,该函数根据正则表达式把满足匹配的内容替换为repl

  • pattern:同findall函数中的pattern
  • repl:指定替换成的新值
  • string:同findall函数中的string
  • count:用于指定最多替换的次数,默认为全部替换
  • flags:同findall函数中的flags

2.3 匹配分割函数

split(pattern, string, maxsplit=0, flags=0)

split函数是将字符串按照指定的正则表达式分隔开,类似于字符串的split方法。

  • pattern:同findall函数中的pattern
  • string:同findall函数中的string
  • maxsplit:用于指定最大分割次数,默认为全部分割
  • flags:同findall函数中的flags

2.4 实际应用

如果上面的函数和参数含义都已经掌握了,还需要进一步通过案例加强理解,接下来举例说明上面的三个函数。

# 导入第三方包
import re

# 取出出字符中所有的天气状态
string8 = "{ymd:'2018-01-01',tianqi:'晴',aqiInfo:'轻度污染'},{ymd:'2018-01-02',tianqi:'阴~小雨',aqiInfo:'优'},{ymd:'2018-01-03',tianqi:'小雨~中雨',aqiInfo:'优'},{ymd:'2018-01-04',tianqi:'中雨~小雨',aqiInfo:'优'}"
print(re.findall("tianqi:'(.*?)'", string8))

# 取出所有含O字母的单词
string9  = 'Together, we discovered that a free market only thrives when there are rules to ensure competition and fair play, Our celebration of initiative and enterprise'
print(re.findall('\w*o\w*',string9, flags = re.I))
# print(re.findall('\w{0,}o\w{0,}',string9,re.I))

# 将标点符号、数字和字母删除
string10 = '据悉,这次发运的4台蒸汽冷凝罐属于国际热核聚变实验堆(ITER)项目的核二级压力设备,先后完成了压力试验、真空试验、氦气检漏试验、千斤顶试验、吊耳载荷试验、叠装试验等验收试验。'
print(re.sub('[,。、a-zA-Z0-9()]','',string10))

# 将每一部分的内容分割开
string11 = '2室2厅 | 101.62平 | 低区/7层 | 朝南 \n 上海未来 - 浦东 - 金杨 - 2005年建'
split = re.split('[-\|\n]', string11)
print(split)
split_strip = [i.strip() for i in split]
print(split_strip)

[‘晴’, ‘阴~小雨’, ‘小雨~中雨’, ‘中雨~小雨’]
[‘Together’, ‘discovered’, ‘only’, ‘to’, ‘competition’, ‘Our’, ‘celebration’, ‘of’]
据悉这次发运的台蒸汽冷凝罐属于国际热核聚变实验堆项目的核二级压力设备先后完成了压力试验真空试验氦气检漏试验千斤顶试验吊耳载荷试验叠装试验等验收试验
['2室2厅 ', ’ 101.62平 ', ’ 低区/7层 ', ’ 朝南 ', ’ 上海未来 ', ’ 浦东 ', ’ 金杨 ‘, ’ 2005年建’]
[‘2室2厅’, ‘101.62平’, ‘低区/7层’, ‘朝南’, ‘上海未来’, ‘浦东’, ‘金杨’, ‘2005年建’]

如上结果所示,在第一个例子中通过正则表达式"tianqi:’(.*?)’“实现目标数据的获取,如果不使用括号的话,就会产生类似"tianqi:‘晴’”,"tianqi:‘阴~小雨’"这样的值,所以,加上括号就是为了分组,且仅返回组中的内容

3 实战应用

import pandas as pd

# 数据读入
df=pd.read_excel(r'D:\desktop\从零开始学Python数据分析与挖掘\第5章 Python数据处理工具--Pandas\data_test03.xlsx')
df.head()
name gender birthday start_work income tel email other
0 赵一 1989/8/10 2012-09-08 15000 13611011234 [email protected] {教育:本科,专业:电子商务,爱好:运动}
1 王二 1990/10/2 2014-03-06 12500 13500012234 [email protected] {教育:大专,专业:汽修,爱好:}
2 张三 1987/3/12 2009-01-08 18500 13515273330 [email protected] {教育:本科,专业:数学,爱好:打篮球}
3 李四 1991/8/16 2014-06-04 13000 13923673388 [email protected] {教育:硕士,专业:统计学,爱好:唱歌}
4 刘五 1992/5/24 2014-08-10 8500 17823117890 [email protected] {教育:本科,专业:美术,爱好:}

针对如上数据,读者可以在不看下方代码的情况下尝试着回答这些关于字符型及日期型的问题:

  • 如何更改出生日期birthday和手机号tel两个字段的数据类型。
  • 如何根据出生日期birthday和开始工作日期start_work两个字段新增年龄和工龄两个字段。
  • 如何将手机号tel的中间四位隐藏起来。
  • 如何根据邮箱信息新增邮箱域名字段。
  • 如何基于other字段取出每个人员的专业信息。
df.dtypes

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第28张图片

# 更改出生日期`birthday`和手机号`tel`两个字段的数据类型
df.birthday=pd.to_datetime(df.birthday,format='%Y/%m/%d')
# from datetime import datetime
# df.birthday.apply(lambda x:datetime.strptime(x,'%Y/%m/%d'))

df.tel=df.tel.astype('str')

df.dtypes

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第29张图片

# 根据出生日期`birthday`和开始工作日期`start_work`两个字段新增年龄和工龄两个字段
from datetime import date,datetime

df['age']=date.today().year-df.birthday.dt.year
df['work_age']=date.today().year-df.start_work.dt.year

df.head(1)
name gender birthday start_work income tel email other age work_age
0 赵一 1989-08-10 2012-09-08 15000 13611011234 [email protected] {教育:本科,专业:电子商务,爱好:运动} 32 9
# 将手机号`tel`的中间四位隐藏起来
df.tel=df.tel.apply(lambda x:x.replace(x[3:7],'****'))

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第30张图片

# 如何根据邮箱信息新增邮箱域名字段
df['email_domain']=df.email.apply(lambda x:x.split('@')[1])

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第31张图片

# 如何基于other字段取出每个人员的专业信息
import re

df['job']=df.other.apply(lambda x:re.findall("专业:(.*?),",x))
# df['job']=df.other.str.findall("专业:(.*?),")

【Python笔记】字符串的处理方法(延伸到pandas)(含正则表达式)_第32张图片

如果需要对每一行应用函数后再做一些特殊处理,要使用apply
如果只是对一列做一个统一操作(只应用一个函数),只用df.col_name.str.func() 即可

你可能感兴趣的:(Python笔记,python,字符串,正则表达式,数据分析)