在数据分析前,首先要进行数据采集。通常,采集到的原始数据大多数是不完整和不一致的“脏”数据,无法直接进行数据挖掘。为了提高挖掘质量,产生了数据预处理技术。数据预处理包括数据清洗,数据集成,数据变换,数据归约等。 数据清洗是发现并纠正数据文件中可识别的错误,如移除重复数据,处理缺失值和空格值,检测和过滤异常值,并检查数据一致性等。通过数据清洗不仅要使通过清洗后的数据变的可用,而且还要使数据变的更加适合进行后续的数据分析工作。8.1.1重复值处理
数据采集所获得的原始数据集中,往往会存在着许多重复数据。所谓重复数据是指在数据结构中所有列的内容都相同,即行重复。而处理重复数据是数据分析中经常要面对的问题之一。
pandas提供了duplicated()和drop_duplicates()函数可用于标记及删除重复数据。
- 1、duplicated()函数
duplicated()函数用于标记Series中的值、Dataframe中的记录行是否是重复,重复为True,不重复为False。
语法格式如下:
pandas.Dataframe.duplicated(subset=None,keep='first')或pandas.Series.duplicated(keep='first')
参数说明:
-
subset:接收特定的string或sequence,用于识别重复的列标签或列标签序列,默认为列标签,默认值为None
-
keep:接收特定的string,first表示除了第一次出现外,其余相同的重复项标记为True;last表示除了最后一次出现外,其余相同的重复项标记为True,False表示将所有的重复项标记为True,默认为first。
-
2、drop_duplicates()函数
drop_duplicates()函数用于删除Series、Dataframe中重复记录,并返回删除重复后的结果
语法格式如下:
pandas.Dataframe.drop_duplicates(subset=None,keep='first',inplace=False)或pandas.Series.drop_duplicates(keep='first',inplace=False)
参数说明:
- subset:接收string或sequence,仅考虑用于标识重复项的某些列,默认情况下使用列。默认值为None
- keep:接收特定的string,first表示删除重复项并保留第一次出现的项;last表示除了最后一次出现外,其余相同的重复项标记为True,False表示将所有的重复项标记为True,默认为first。
- inplace:接收boolean,True表示直接修改原对象,False表示创建一个副本,修改副本,原对象不变,默认为False
【例】有一个手机评论数据Mobile.csv文件,改文件的数据列包括手机品牌、价格和评分。现在要求完成去除改文件中的重复值,其示例代码如下:
import pandas as pd
df=pd.read_csv('P:/data/Mobile.csv',encoding='GBK',low_memory=False) print('原数据为:') df
原数据为:
327591 rows × 21 columns
补充:iloc参数用法:.loc先行后列,中间用逗号(,)分割https://www.py.cn/faq/python/18973.html
#取df中0-4列数据 df1=df.iloc[:,0:4] print(df1)
Samsung 199.99 5 1 0 Samsung 199.99 4 0 1 Samsung 199.99 4 0 2 Samsung 199.99 1 1 3 Samsung 199.99 2 0 4 Samsung 199.99 2 0 ... ... ... .. .. 327586 Samsung 79.95 5 0 327587 Samsung 79.95 3 0 327588 Samsung 79.95 5 0 327589 Samsung 79.95 3 0 327590 Samsung 79.95 4 0 [327591 rows x 4 columns]
#标识重复项 data=df1.duplicated(keep='first') print(data)
0 False 1 True 2 False 3 False 4 True ... 327586 True 327587 True 327588 True 327589 True 327590 True Length: 327591, dtype: bool
#删除重复项 data1=df1.drop_duplicates(keep='first') print(data1)
Samsung 199.99 5 1 0 Samsung 199.99 4 0 2 Samsung 199.99 1 1 3 Samsung 199.99 2 0 5 Samsung 199.99 5 0 6 Samsung 199.99 3 0 ... ... ... .. ... 327459 Samsung 79.95 5 3 327493 Samsung 79.95 5 16 327498 Samsung 79.95 1 4 327500 Samsung 79.95 5 12 327543 Samsung 79.95 2 NaN [36830 rows x 4 columns]8.1.2 缺失值的处理
常见的缺失值处理方式有过滤和填充。在Python中,pandas使用浮点值NaN表示浮点数和非浮点数组中的缺失值,同时Python内置None值也会被当作是缺失值。在处理缺失值之前,首先要判断缺失值是否存在,然后再对缺失值进行删除、填充或者不处理的 *** 作1.判断缺失值的函数
(1)isnull()函数:用于检查空值或缺失值的对象;如果有空值或缺失值则返回True,否则返回False。 (2)notnull()函数:用于检查不为空值或缺失值的对象;如果有空值或缺失值则返回False,否则返回True。 通过isnull()函数和sum()函数可以获得Series和Dataframe中缺失值的数量2.处理缺失值的方法:
数据缺失值的处理方法有以下3种
·删除含有缺失值的记录
·进行数据插补
·不处理空值或缺失值
(1)删除含有缺失值的记录在数据分析中,如果数据集的样本很大,并且在删除含有缺失值的记录后,不会影响分析结果的客观性和准确性时,一般是使用dropna()函数直接将空值或缺失值的数据删除
dropna()函数的语法格式如下: Dataframe.dropna(axis=0,how='any',thresh=None,subset=None,inplace=False)
参数说明:
- axis:指定删除方向,axis=0按行删除,axis=1按列删除,默认为0
- how:取值为“all”表示这一行或列中的元素全部缺少(为NaN)才删除这一行或列;取值为“any”表示这一行或列中只要有缺失值,就删除这一行或列
- thesh:一行或一列中至少出现了thesh个才删除
- subset:在某些列的子集中选择了缺失值的列删除,不在子集中的含有缺失值的行或列不会被删除
- inplace:筛选缺失值后,获得的新数据是存为副本还是直接在原数据上修改
【例】:导入Excel成绩表grade.xls中的grade1表,完成各种不同情况下删除缺失值的 *** 作,其示例代码如下:
import pandas as pd
#导入成绩数据 df=pd.read_excel('p:/data/grade.xls',sheet_name='grade1') df
#所有值全为缺失值才删除 df1=df.dropna(how='all')
#输出df1的前5行 print(df1.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 NaN NaN 2 2017003 NaN 60.0 3 2017004 87.0 NaN 4 2017005 NaN NaN
#删除至少出现过两个缺失值的行 df1=df.dropna(thresh=2,axis=0) df1
#输出df1的前10行 print(df.head(10))
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 NaN NaN 2 2017003 NaN 60.0 3 2017004 87.0 NaN 4 2017005 NaN NaN 5 2017006 NaN 76.0 6 2017007 87.0 NaN 7 2017008 90.0 83.0 8 2017009 NaN 80.0 9 2017010 90.0 NaN
#删除subset中指定的列含有缺失值的行 df1=df.dropna(subset=['exam']) #输出df1的前5行 print(df1.head())
stu_id Normal exam 0 2017001 80.0 66.0 2 2017003 NaN 60.0 5 2017006 NaN 76.0 7 2017008 90.0 83.0 8 2017009 NaN 80.0
#删除含有缺失值的列 print(df.dropna(axis=1))
stu_id 0 2017001 1 2017002 2 2017003 3 2017004 4 2017005 5 2017006 6 2017007 7 2017008 8 2017009 9 2017010 10 2017011 11 2017012 12 2017013 13 2017014 14 2017015 15 2017016 16 2017017 17 2017018 18 2017019 19 2017020 20 2017021 21 2017022 22 2017023 23 2017024 24 2017025 25 2017026 26 2017027 27 2017028 28 2017029 29 2017030 30 2017031 31 2017032 32 2017033 33 2017034 34 2017035 35 2017036 36 2017037 37 2017038
#只要有缺失值就删除,并且直接在原数据上修改 df1=df.dropna(how='any',inplace=True) print(df)
stu_id Normal exam 0 2017001 80.0 66.0 7 2017008 90.0 83.0 12 2017013 81.0 62.0 13 2017014 86.0 83.0 14 2017015 87.0 74.0 16 2017017 84.0 60.0 18 2017019 91.0 85.0 19 2017020 86.0 61.0 20 2017021 91.0 81.0 22 2017023 95.0 81.0 23 2017024 88.0 91.0 24 2017025 88.0 84.0 25 2017026 91.0 80.0 26 2017027 91.0 89.0 27 2017028 90.0 83.0 28 2017029 88.0 68.0 29 2017030 74.0 47.0 30 2017031 81.0 50.0 31 2017032 78.0 48.0 32 2017033 81.0 60.0 33 2017034 84.0 89.0 34 2017035 87.0 79.0 35 2017036 82.0 70.0 36 2017037 89.0 60.0 37 2017038 90.0 64.0(2)数据插补法
在数据分析中,如果数据集的样本比较少或者由于删除含有缺失值的记录会影响到数据分析结果的客观性和准确性时,就需要根据数据插补的方法来选择填充值,然后再使用fillna()函数对空值或缺失值进行填充。 fill函数格式如下:
Dataframe.fillna(value=None,method=None,axis=None,inplace=False,limit=None,downcast=None,**kwargs)
参数说明:
- value:接收常数,dict,Series或Dataframe,表示填充缺失值的值
- method:表示填充缺失值的方法,method的取值为{‘pad’,‘ffill’,‘backfill’,‘bfill’,‘None’}。pad/ffill:用前一个非缺失值去填充该缺失值。backfill/bfill:用下一个非缺失值去填充该缺失值。none:指定一个值去替换缺失值(缺省默认这种方式)
- axis:指定填充方向,axis=1按列填充,axis=0按行填充
- inplace:接收True或False。True表示直接修改原对象,False表示创建一个副本,修改副本,原对象不变,默认为False
- limit:表示限制填充的个数,如果limit=2,则只填充两个缺失值
- downcast:默认为None,如果需要将填充的值向下转换为适当的相等数据类型的数值,如将float64数据类型转换为int64数据类型时,则此参数的值为“infer”
注意:method参数不能和value参数同时出现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JcGNn9xW-1637637711978)(数据插补方法.jpg)]
【例】导入Excel成绩表grade.xls中的grade1表,完成以下 *** 作
- (1)查看该表前五行的缺失值,分别用0和字典填充缺失值,但不修改原数据
- (2)分别指定不同的method参数,观察填充缺失值情况
- (3)将Normal属性的缺失值用中位数替换,exam属性的缺失值用均值替换
- (4)用0替换缺失值,并修改原数据
- 代码如下
import pandas as pd
#导入数据 df=pd.read_excel('p:/data/grade.xls',sheet_name='grade1') #1.查看前5行 print(df.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 NaN NaN 2 2017003 NaN 60.0 3 2017004 87.0 NaN 4 2017005 NaN NaN
#查看缺失值的数量 print(df.isnull().sum())
stu_id 0 Normal 8 exam 9 dtype: int64
#用0填充 df1=df.fillna(0) print(df1.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 0.0 0.0 2 2017003 0.0 60.0 3 2017004 87.0 0.0 4 2017005 0.0 0.0
#用字典填充 df2=df.fillna({'Normal':60,'exam':40}) print(df2.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 60.0 40.0 2 2017003 60.0 60.0 3 2017004 87.0 40.0 4 2017005 60.0 40.0
#观察原来的数据df没有改变 print(df.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 NaN NaN 2 2017003 NaN 60.0 3 2017004 87.0 NaN 4 2017005 NaN NaN
#指定method='ffill'/'pad':用前一个非缺失值填充该缺失值 df2=df.fillna(method='ffill') print(df2.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 80.0 66.0 2 2017003 80.0 60.0 3 2017004 87.0 60.0 4 2017005 87.0 60.0
#指定method = 'bfill'/'backfill':用下一个非缺失值填充该缺失值 df2 = df.fillna(method='bfill') print(df2.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 87.0 60.0 2 2017003 87.0 60.0 3 2017004 87.0 76.0 4 2017005 87.0 76.0
#6.将exam列的缺失值用均值替换 exa_mea = df['exam'].fillna(df['exam'].mean()) print(exa_mea.head())
0 66.000000 1 72.275862 2 60.000000 3 72.275862 4 72.275862 Name: exam, dtype: float64
#将Normal列的缺失值用中位数替换 Nor_med = df['Normal'].fillna(df['Normal'].median()) print(Nor_med.head())
0 80.0 1 87.0 2 87.0 3 87.0 4 87.0 Name: Normal, dtype: float64
#7.指定inplace参数为True print(df.fillna(0,inplace=True))
None
#观察原来数据df发生改变 print(df.head())
stu_id Normal exam 0 2017001 80.0 66.0 1 2017002 0.0 0.0 2 2017003 0.0 60.0 3 2017004 87.0 0.0 4 2017005 0.0 0.08.1.3异常值处理
所谓异常值,就是在数据集中存在不合理的值,又称离群点。例如年龄为负数,成绩大于100或小于零,商品评分超出5分或商品日销售量远远超过年销售量等,都属于异常值的范围。1. 判别数据集中异常值方法
(1)散点图分析 (2)简单统计分析 例如,年龄属性值的区间规定为[0:150],如果数据集样本中的年龄值不在该区间范围内,则表示该样本的年龄属性属于异常值。 (3)3δ原则 3δ原则是指当数据服从正态分布时,根据正态分布的定义可知,距离平均值3δ之外的概率为 P(|x-μ|>3δ) <= 0.003 ,这是属于极小的概率事件, 因此,当样本距离平均值大于3δ时,则认定该样本为异常值。 (4)箱型图分析 箱型图提供了一个识别异常值的标准,即大于或小于箱型图设定的上下界的数值即为异常值。2. 异常值的处理方法
常用的异常值处理方法有以下4种。 (1)删除含有异常值的记录。 (2)将异常值视为缺失值,按照缺失值的处理方法来处理。 (3)用平均值来修正异常值。 (4)对异常值不处理。
在处理异常值时,有些异常值可能含有有用信息,因此,如何判定和处理异常值,需视情况而定。在数据量较多时,可用散点图和描述性的统计来查看数据基本情况,发现异常值,并借助箱线图进行监测
【例】有餐厅销售数据表sale.xls,在该数据表中有日期和销量两列数据,要求分析该数据表中销量数据的异常值,并将异常值用销量数据替换掉
数据分析思路:首先读取文件中的数据,并对销量数据进行描述性统计分析。通过描述性统计分析发现异常值,然后,运用散点图寻找异常值,最后,将异常值用销量数据的中位数替换。代码如下:
8.2 数据合并通过数据合并,可以将多个数据集整合到一个数据集中,常用的数据合并函数有merge(),join(),concat(),append(),combine_first()
8.2.1按键连接数据 1.merge()函数在pandas中,通过两个数据集上一个或多个键来合并数据时,可使用merge()函数。函数格式如下:
pandas.merge(left,right,how='inner',on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False,suffixes=('_x','_y'),copy=True,indicator=False)
函数参数说明如下:
- left:参与合并的左侧Dataframe
- right:参与合并的右侧Dataframe
- how:表示连接方式,取值{inner,outer,left,right},默认为inner内连接,其结果是取两个数据集中键值交集的数据;outer外连接,其结果是取两个数据集中键值并集的数据,对不匹配的键所对应的数据用NaN填充;left左连接,取左侧全部数据,右侧取与左侧想匹配的键所对应的数据,不匹配的键所对应的数据用NaN填;right右连接,取右侧全部数据,左侧取与右侧相匹配的键所对应的数据,不匹配的键所对应的数据用NaN填充
- on:表示用于连接的列名,必须同时存在于左右两个Dataframe对象中,如果未传递且left_index和right_index为False,则Dataframe中列的交集将作为连接键
- left_on:表示左侧的Dataframe中用作连接键的列,可以是列名、索引级名称,也可以是长度等于Dataframe长度的数组
- right_on:表示左侧的Dataframe中用作连接键的列,可以是列名、索引级名称,也可以是长度等于Dataframe长度的数组
- left_index:如果为True,则使用左侧Dataframe中的索引(行标签)作为其连接键
- right_index:如果为True,则使用右侧Dataframe中的索引(行标签)作为其连接键
- suffixes:字符串值组成的元组,用于指定当左右Dataframe存在相同列名时,在列名后面附加的后缀名称,默认为(’_x’,’_y’),例如,左右两个Dataframe对象有"data",则结果中就会出现’data_x’和’data_y’
- copy:默认为True,表示总是将数据复制到数据结构中,大多数情况下设置为False可以提高性能
- indicator:默认为False,如果设置为True,将显示合并数据中每行来源的信息添加到名为_merge的列中输出,例如,只来自左边(left_only)、两者(both)、只来自右边(right_only)
【例】创建产品信息(info)和产品销售(sale)数据集,并完成下列对产品信息和产品销售数据集的数据合并 *** 作
(1)使用默认连接方式连接产品信息和产品销售数据集
(2)按照指定“产品编号”列名合并产品信息和产品销售数据集
(3)分别用left、right、outer连接方式连接数据集
(4)根据“产品编号”和“品牌”多个键进行连接
(5)对重复的列名处理
(6)将索引作为连接的键
其代码如下:
import pandas as pd
#创建产品信息(info)和产品销售(sale)数据集 info = pd.Dataframe({'产品编号':list('ABCD'),'类型名称':['电视机','手机','电脑','空调'], '品牌':['格力','康佳','海信','TCL']},index=range(1001,1005)) info.columns.name='产品信息' info.index.name='编号' print(info)
产品信息 产品编号 类型名称 品牌 编号 1001 A 电视机 格力 1002 B 手机 康佳 1003 C 电脑 海信 1004 D 空调 TCL
sale = pd.Dataframe({'产品编号':list('ABECDF'),'品牌':['格力','康佳','海信','TCL','康佳','格力'], '价格':[3600,1500,4500,2000,2300,3500]},index=range(1001,1007)) sale.columns.name='产品销售' sale.index.name='编号' print(sale)
产品销售 产品编号 品牌 价格 编号 1001 A 格力 3600 1002 B 康佳 1500 1003 E 海信 4500 1004 C TCL 2000 1005 D 康佳 2300 1006 F 格力 3500
#1. 使用默认连接方式连接产品信息和产品销售数据集 print(pd.merge(info,sale)) #2. 按照指定“产品编号”列名合并产品信息和产品销售数据集 print(pd.merge(info,sale,on='产品编号')) #3. 分别用left、right、outer连接方式连接数据集。 print(pd.merge(info,sale,how='left')) print(pd.merge(info,sale,how='right')) print(pd.merge(info,sale,how='outer'))
产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600 1 B 手机 康佳 1500 产品编号 类型名称 品牌_x 品牌_y 价格 0 A 电视机 格力 格力 3600 1 B 手机 康佳 康佳 1500 2 C 电脑 海信 TCL 2000 3 D 空调 TCL 康佳 2300 产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600.0 1 B 手机 康佳 1500.0 2 C 电脑 海信 NaN 3 D 空调 TCL NaN 产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600 1 B 手机 康佳 1500 2 E NaN 海信 4500 3 C NaN TCL 2000 4 D NaN 康佳 2300 5 F NaN 格力 3500 产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600.0 1 B 手机 康佳 1500.0 2 C 电脑 海信 NaN 3 D 空调 TCL NaN 4 E NaN 海信 4500.0 5 C NaN TCL 2000.0 6 D NaN 康佳 2300.0 7 F NaN 格力 3500.0
#4.根据产品编号和品牌多个键进行连接 print(pd.merge(info,sale,on=['产品编号','品牌'])) #5.对重复的列名进行处理 print(pd.merge(info,sale,on='产品编号',suffixes=('_1','_2'))) #6.将索引作为连接的键 print(pd.merge(info,sale,on=['产品编号','品牌']))
产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600 1 B 手机 康佳 1500 产品编号 类型名称 品牌_1 品牌_2 价格 0 A 电视机 格力 格力 3600 1 B 手机 康佳 康佳 1500 2 C 电脑 海信 TCL 2000 3 D 空调 TCL 康佳 2300 产品编号 类型名称 品牌 价格 0 A 电视机 格力 3600 1 B 手机 康佳 15002.join()函数
除了merge()函数外,还可以使用join()函数来实现根据特定的列和索引进行合并数据的 *** 作。join()函数默认是通过index来进行连接,也可以通过设置参数“on”来指定连接的列。 参数格式如下:
left.join(right,on='keys')
函数功能:将left的’keys’列和right的索引作为关键字进行比较,相同的进行合并。其等效于pandas.merge(left,right,left_on='key',right_index=True,how="left")示例代码如下:
import numpy as np import pandas as pd left = pd.Dataframe({'one':np.arange(4),'two':list('abcd'), 'key':['k0','k1','k0','k1']}) right=pd.Dataframe({'three':[4,5],'four':['e','f']}, index=['k0','k1']) result=left.join(right,on='key') print(left,'n',right,'n',result)
one two key 0 0 a k0 1 1 b k1 2 2 c k0 3 3 d k1 three four k0 4 e k1 5 f one two key three four 0 0 a k0 4 e 1 1 b k1 5 f 2 2 c k0 4 e 3 3 d k1 5 f8.2.2 沿轴连接数据 1.concat()函数
在pandas中,利用concat()函数可以沿轴将数据进行简单的连接。但concat方法不会去重,如要实现去重的效果,可以使用drop_duplicates方法。 按轴向连接数据就是单纯地将两个表拼接,这个过程也被称作连接(concatenation)、绑定(binding)或堆叠(stacking)。 concat()函数格式如下:
pandas.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False,keys=None,levels=None,names=None,names=None,verify_integrity=False,copy=True,sort=False)
参数说明如下:
- sort: 如果True,则将合并的数据进行排序,默认为False,但在横向外连接或者ignore_index=True时要设置此参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x1QweDdf-1637637711983)(concat()]参数说明.jpg)
【例】使用concat()函数,通过选择不同的参数,观察实现多个数据集的沿轴连接的效果,其示例代码如下:
import numpy as np import pandas as pd
#定义3个Series s1 = pd.Series([0, 1, 2], index=['a', 'b', 'c']) s2 = pd.Series([3, 4, 5, 6], index=['d', 'e', 'f', 'g']) s3 = pd.Series([7, 8, 9], index=['h', 'i', 'j']) print('将s1,s2,s3纵向外连接') result = pd.concat([s1, s2, s3]) print(result)
将s1,s2,s3纵向外连接 a 0 b 1 c 2 d 3 e 4 f 5 g 6 h 7 i 8 j 9 dtype: int64
print('将s1,s2,s3横向外连接') result = pd.concat([s1, s2, s3], axis=1,sort=False) print(result)
将s1,s2,s3横向外连接 0 1 2 a 0.0 NaN NaN b 1.0 NaN NaN c 2.0 NaN NaN d NaN 3.0 NaN e NaN 4.0 NaN f NaN 5.0 NaN g NaN 6.0 NaN h NaN NaN 7.0 i NaN NaN 8.0 j NaN NaN 9.0
print('将s1*2,s3纵向外连接') s4 = pd.concat([s1 * 2, s3]) print(s4) print('将s1,s4横向外连接') result = pd.concat([s1, s4], axis=1,sort=False) print(result) print('将s1,s4横向内连接') result = pd.concat([s1, s4], axis=1, join='inner') print(result)
将s1*2,s3纵向外连接 a 0 b 2 c 4 h 7 i 8 j 9 dtype: int64 将s1,s4横向外连接 0 1 a 0.0 0 b 1.0 2 c 2.0 4 h NaN 7 i NaN 8 j NaN 9 将s1,s4横向内连接 0 1 a 0 0 b 1 2 c 2 4
print('将s1,s4横向外连接,自定义索引') result = pd.concat([s1, s4], axis=1 ) print(result) print('将s1,s2,s3纵向外连接,设置层次索引') result = pd.concat([s1, s1, s3], keys=['one', 'two', 'three']) print(result)
将s1,s4横向外连接,自定义索引 0 1 a 0.0 0 b 1.0 2 c 2.0 4 h NaN 7 i NaN 8 j NaN 9 将s1,s2,s3纵向外连接,设置层次索引 one a 0 b 1 c 2 two a 0 b 1 c 2 three h 7 i 8 j 9 dtype: int64
print('将s1,s2,s3横向外连接,设置层次索引') result = pd.concat([s1, s2, s3], axis=1, keys=['one', 'two', 'three'], sort=False) print(result)
将s1,s2,s3横向外连接,设置层次索引 one two three a 0.0 NaN NaN b 1.0 NaN NaN c 2.0 NaN NaN d NaN 3.0 NaN e NaN 4.0 NaN f NaN 5.0 NaN g NaN 6.0 NaN h NaN NaN 7.0 i NaN NaN 8.0 j NaN NaN 9.0
#定义一个2个Dataframe df1 = pd.Dataframe(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'], columns=['one', 'two']) df2 = pd.Dataframe(5 + np.arange(4).reshape(2, 2), index=['a', 'c'], columns=['three', 'four']) print('将df1,df2横向外连接,设置层次索引') result = pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],sort=False) print(result) print('使用字典设置层次索引,横向外连接') result = pd.concat({'level1': df1, 'level2': df2}, axis=1,sort=False) print(result) print('将df1,df2横向外连接,设置层次索引和层次索引的级别名称') result = pd.concat([df1, df2], axis=1, keys=['level1', 'level2'], names=['upper', 'lower'],sort=False) print(result)
将df1,df2横向外连接,设置层次索引 level1 level2 one two three four a 0 1 5.0 6.0 b 2 3 NaN NaN c 4 5 7.0 8.0 使用字典设置层次索引,横向外连接 level1 level2 one two three four a 0 1 5.0 6.0 b 2 3 NaN NaN c 4 5 7.0 8.0 将df1,df2横向外连接,设置层次索引和层次索引的级别名称 upper level1 level2 lower one two three four a 0 1 5.0 6.0 b 2 3 NaN NaN c 4 5 7.0 8.0
#将两个不相同的列的数据合并 df1 = pd.Dataframe(np.random.randn(3, 4), columns=['a', 'b', 'c', 'd']) df2 = pd.Dataframe(np.random.randn(2, 3), columns=['b', 'd', 'a']) print('df1, df2纵向外连接,忽略原index,重建索引') print(pd.concat([df1, df2], ignore_index=True,sort=False))
df1, df2纵向外连接,忽略原index,重建索引 a b c d 0 0.484948 2.018484 -0.023108 0.110072 1 -0.058997 0.701099 0.509739 0.151530 2 -0.831136 0.867745 0.141327 -0.815501 3 -0.917513 -2.420508 NaN -0.213645 4 -1.791165 0.064137 NaN 1.6712992.append()函数
append()函数是concat()函数的简略形式,但是append()函数只能在axis=0上进行数据合并,函数格式如下:
left.append(right)或left.append(right,ignore_index=True)该函数的功能为:将left指定数据集与right指定数据集进行纵向合并。其中,Dataframe与Series进行合并时,需要使用参数ignore_index=True。其示例代码如下:
import numpy as np import pandas as pd
left=pd.Dataframe({'one':np.arange(4),'two':list('abcd')}) right=pd.Dataframe({'three':[4,5],'four':['e','f']}) s1=pd.Series([0,1,2],index=['a','b','c']) result=left.append(right,sort=False) result1=left.append(s1,ignore_index=True) print('左边数据:n',left,'右边数据:n',right,'合并数据:n',result) print('左边数据:n',left,'右边数据:n',s1,'合并数据:n',result1)
左边数据: one two 0 0 a 1 1 b 2 2 c 3 3 d 右边数据: three four 0 4 e 1 5 f 合并数据: one two three four 0 0.0 a NaN NaN 1 1.0 b NaN NaN 2 2.0 c NaN NaN 3 3.0 d NaN NaN 0 NaN NaN 4.0 e 1 NaN NaN 5.0 f 左边数据: one two 0 0 a 1 1 b 2 2 c 3 3 d 右边数据: a 0 b 1 c 2 dtype: int64 合并数据: one two a b c 0 0.0 a NaN NaN NaN 1 1.0 b NaN NaN NaN 2 2.0 c NaN NaN NaN 3 3.0 d NaN NaN NaN 4 NaN NaN 0.0 1.0 2.08.2.3合并重置数据
合并重叠数使用是combine_first()函数,该函数的语法格式:
obj1.combine_first(obj2)其中,obj1为函数调用对象的数据集,obj2为函数参数对象的数据集。该函数的作用是用函数参数对象中的数据为函数调用对象的缺失数据“打补丁”。即填充函数调用对象中的数据缺失值。
【例】示例代码如下
import numpy as np import pandas as pd
s1=pd.Series([2,np.nan,4.2,np.nan,5.5,np.nan],index=['a','b','c','d','e','f']) s2=pd.Series(np.arange(len(s1),dtype=np.float64),index=['a','b','c','d','e','f']) result=s2[:-3].combine_first(s1[3:]) print(s1,'n',s2,'n',result) df1=pd.Dataframe({'a':[np.nan,2.,4.,np.nan], 'b':[1.,np.nan,3.,np.nan], 'c':range(2,18,4)}) df2=pd.Dataframe({'a':[3.,np.nan,5.,7.,9.], 'b':[np.nan,2.,4.,6.,8.]}) result1=df1.combine_first(df2) print(df1,'n',df2,'n',result)
a 2.0 b NaN c 4.2 d NaN e 5.5 f NaN dtype: float64 a 0.0 b 1.0 c 2.0 d 3.0 e 4.0 f 5.0 dtype: float64 a 0.0 b 1.0 c 2.0 d NaN e 5.5 f NaN dtype: float64 a b c 0 NaN 1.0 2 1 2.0 NaN 6 2 4.0 3.0 10 3 NaN NaN 14 a b 0 3.0 NaN 1 NaN 2.0 2 5.0 4.0 3 7.0 6.0 4 9.0 8.0 a 0.0 b 1.0 c 2.0 d NaN e 5.5 f NaN dtype: float648.3 数据抽取
数据抽取,也成为数据拆分,他是通过保留、抽取源数据表中的某些字段、记录的部分信息来形成一些新字段和新纪录
8.3.1 字段抽取与拆分字段抽取是根据已知列数据的开始和结束位置,抽取出新的列。字段抽取采用slice()函数,该函数的语法格式: Series.str.slice(start=None, stop=None) 函数中的参数说明: start:表示字段抽取的开始位置。 stop:表示字段抽取的结束位置。
import numpy as np import pandas as np
#导入数据 data=pd.read_csv('p:/data/goods_sales.csv',encoding='GBK') print(data)
用户ID 商品信息 数量 单价 电话 0 10001 Gree;空调;KFR-35GW/NhBaD3 1 3149 18573351234 1 10010 惠普(HP);电脑; 15-cs1013TX? 1 5569 18573354324 2 10013 联想;电脑;ThinkPad T480S(06CD) 1 16234 18810012345 3 10021 Gree;空调; KFR-72LW/NhHaD3 1 5690 18664511234 4 10023 TCL;冰箱;BCD-163KF1 1 1049 18872345636 5 10016 Haier;冰箱;BCD-118TMPA 2 999 18573323312 6 10026 Haier;洗衣机;XQB80 - KM12688 2 1399 13673327765 7 10034 Haier;洗衣机;XQB60-M12699T 4 999 13567542343 8 10027 Haier;冰箱;BCD-216WMPT 3 1999 13873325687
#将'商品信息'拆分成3列的数据框 #newData = data['商品信息'].str.split(';', 3, True) #newData.columns = ['品牌', '分类','型号'] #设置列名 #print(newData)
#df = data.drop('商品信息', axis=1).join(newData) #result = df.groupby(by=['品牌','数量']).agg(np.sum) #print(result)
#result = df.groupby(by=['分类'])['数量'].agg([( '数量',np.sum)]) #print(result)
#抽取电话号码地区号 #telData = data['电话'].astype(str) #areas = telData.str.slice(3, 7) #print(areas) #newDf = data.drop('电话', axis=1).join(areas) #print(newDf) #result = newDf.groupby(by=['电话','数量']).agg(np.sum) #print(result)8.3.2 记录抽取
记录抽取是指根据一定的条件,对数据进行抽取。 记录抽取函数: datafram[condition] 其中,condition为过滤条件。函数返回值是DataFram。 常用的条件类型
- ① 比较运算:大于(>),小于(<),大于等于(>=),小于等于(<=),不等于(!=)。
- ② 范围运算:between(left,right)。
- ③ 空值匹配:pandas.isnull(column)。
- ④字符匹配:str.contains(patten,na=False),其中na参数是指空值的处理方式,如为False,不匹配空值。
- ⑤逻辑运算:与(&),或(|),取反(not)。
在数据处理时,有时需要对数据的结构进行重排,也称作是重塑(reshape)或者轴向旋转(pivot)。在pandas中提供了实现重塑的两个函数,即stack()函数和unstuck()函数。 常见的数据层次化结构有两种,一种是表格,如图8-3所示,另一种是“花括号”,如图8-4所示。1.stack函数
1、stack()函数 stack()函数将数据从”表格结构“变成”花括号结构“,即将其行索引变成列索引。2.unstack()函数
2、unstack()函数 unstack()函数将数据从”花括号结构“变成”表格结构“,即要将其中一层的列索引变成行索引。
- 1.stack:将数据的列“旋转”为行
- 2.unstack:将数据的行“旋转”为列
- 3.stack和unstack默认 *** 作为最内层
- 4.stack和unstack默认旋转轴的级别将会成果结果中的最低级别(最内层)
- 5.stack和unstack为一组逆运算 *** 作
#创建Dataframe,行索引名为state,列索引名为number import pandas as pd import numpy as np data = pd.Dataframe(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colorado'],name='state') ,columns=pd.Index(['one','two','three'],name='number')) data
#将Dataframe的列旋转为行,即stack *** 作。 result = data.stack() result
state number Ohio one 0 two 1 three 2 Colorado one 3 two 4 three 5 dtype: int32
#将Dataframe的行旋转为列,即unstack *** 作。 result.unstack()
#stack和unstack逆运算 s1 = pd.Series([0,1,2,3],index=list('abcd')) s2 = pd.Series([4,5,6],index=list('cde')) data2 = pd.concat([s1,s2],keys=['one','two']) data2
one a 0 b 1 c 2 d 3 two c 4 d 5 e 6 dtype: int64
data2.unstack().stack()
one a 0.0 b 1.0 c 2.0 d 3.0 two c 4.0 d 5.0 e 6.0 dtype: float648.5 映射与数据转换
映射就是创建一个映射关系列表,把元素和一个特定的标签或者字符串绑定起来。定义映射关系最好是使用字典。 例如:map = {‘label1’:’value1’,label2’:’value2’, … } 在pandas中提供了利用映射关系来实现某些 *** 作的函数如下。 replace()函数:替换元素 map()函数:新建一列 rename()函数:替换索引8.5.1 用映射替换元素
1、利用replace()函数替换元素
例如,创建字典fruits用于指明水果标识和水果名称的映射关系。 fruits = {101:'orange',102:'apple',103:'banana'} 如要将用于存储水果标识、水果数量和单价的Dataframe对象中的水果标识替换成水果名称,就需要运用replace()函数,通过fruits映射关系来实现元素的替换
replace()函数格式:
obj.replace(to_replace=None,Value=None,inplace=False,limit=None,regex=False,method='pad')
参数说明:
- obj:Dataframe或Series对象
- to_replace:接收标量、字典、列表、str、正则表达式,默认为None;用于替换与to_replace匹配的任何值的值;对于Dataframe,可以使用dict来指定每列使用哪个值(不在dict中的列将不会被填充);还允许使用正则表达式、字符串、列表或这些对象的dict
- inplace :bool, 默认 False如果是真的,在适当的地方。注意:这将修改这个对象上的任何其他视图(例如,ataframe中的一个列)。如果为真,则返回调用者。
- limit : int, 默认None向前或向后填充的最大尺寸gap。
- regex :bool或与to_replace相同的类型, 默认False,是否将to_replace和/或value解释为正则表达式。如果这是True,那么to_replace必须是一个字符串。也可以是正则表达式或正则表达式的列表、dict或数组,在这种情况下to_replace必须为None。
- method :{‘pad’, ‘ffill’, ‘bfill’, None}用于替换时,当to_replace是标量时,列表或元组,值为None时使用的方法。
#【例】利用replace函数和映射关系实现将水果数据框中水果表示替换成水果名称 import numpy as np import pandas as pd
#创建水果标识与水果名称的映射关系 fruits = {101:'orange',102:'apple',103:'banana'} #创建水果数据框Dataframe data = pd.Dataframe({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000] ,'price':[3.56,4.2,2.5]}) #用映射替换'fru_No'列的元素 newDf = data.replace(fruits) print(newDf)
fru_No fru_Num price 0 orange 1000 3.56 1 apple 2000 4.20 2 banana 3000 2.50
【例】replace函数应用
import numpy as np import pandas as pd from pandas import Series,Dataframe s = Series([-1000,-999,2,3,4,5,-2000]) #单数值替换 print(s.replace(-2000,np.nan))
0 -1000.0 1 -999.0 2 2.0 3 3.0 4 4.0 5 5.0 6 NaN dtype: float64
#将多个数值替换 print(s.replace([-1000,-999],0))
0 0 1 0 2 2 3 3 4 4 5 5 6 -2000 dtype: int64
#不同的值进行不同的替换 print(s.replace([-1000,-999],[np.nan,0]))
0 NaN 1 0.0 2 2.0 3 3.0 4 4.0 5 5.0 6 -2000.0 dtype: float64
#用字典方式进行不同的替换 print(s.replace({-1000:np.nan,-999:0,-2000:np.nan}))
0 NaN 1 0.0 2 2.0 3 3.0 4 4.0 5 5.0 6 NaN dtype: float648.5.2 用映射添加元素
在上面的例题中中介绍了利用函数和映射来实现将水果标识替换成水果名称的方法。但是有时需要保留水果标识,将水果名称添加到数据集中。那么,这时可利用map()函数,通过构建fruits映射关系来实现元素的添加。
map()函数是作用于Series或Dataframe对象的一列,它接收一个函数或表示映射关系的字典作为参数,格式如下:
Series.map(arg,na_action=None)
参数说明:
- arg:结合搜function、dict、Series,表示映射通信
- na_action:取值为{无,‘忽略’},默认值为None,如果为“忽略”,则传播NA值,而不是将他们传递给映射关系
【例】利用map()函数和映射关系实现将水果名称添加到水果数据框中
import pandas as pd
# 创建水果标识与水果名称的映射关系 fruits={101:'orange',102:'apple',103:'banana'} #创建水果数据框Dataframe data=pd.Dataframe({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000], 'price':[3.56,4.2,2.5]}) #用映射为data添加fru_name元素 data['fru_name']=data['fru_No'].map(fruits) print(data)
fru_No fru_Num price fru_name 0 101 1000 3.56 orange 1 102 2000 4.20 apple 2 103 3000 2.50 banana8.5.3 重命名索引
在数据处理中,有时需要使用映射关系转换轴标签。pandas的rename()函数,是以表示映射关系的字典对象作为参数,替换轴的索引标签。 rename()函数的基本语法格式:
Dataframe.rename(mapper=None,index=None,columns=None,axis=None,copy=True,inplace=False,level=None)或Series.rename(index=None,**kwargs)
参数说明:
- mapper,index,columns: 接收dict或function,表示将dict或函数转换为应用于该轴的值,使用mapper参数要指定映射器;使用columns参数可重命名各列
- axis:接收int或str,可选,表示映射器定位的轴,可以使轴名称(“index”,“columns”)或数字(0,1
),默认为“index”。 - copy:接收boolean。默认为True,表示是否复制数据
- inplace:接收boolean,默认为False,如果为True,将会修改原来的数据
- level:接收int或level name,默认为None,如果是MultiIndex,只重命名指定级别中的标签
rename()函数返回值是Dataframe或Series
【例】利用rename()函数和映射关系重命名水果数据框的行索引和列索引
import pandas as pd #创建行索引的映射关系 reindex={0:'row1',1:'row2',2:'row3'}
#创建水果数据框Dataframe data = pd.Dataframe({'fru_No':[101,102,103],'fru_Num':[1000,2000,3000] ,'price':[3.56,4.2,2.5]})
#用映射重命名水果数据框的行索引,产生新Dataframe,但原数据不改变 newDf = data.rename(reindex) print(newDf,'n',data)
fru_No fru_Num price row1 101 1000 3.56 row2 102 2000 4.20 row3 103 3000 2.50 fru_No fru_Num price 0 101 1000 3.56 1 102 2000 4.20 2 103 3000 2.50
#用映射重命名水果数据框的行索引,产生新Dataframe,但原数据改变 newDf = data.rename(reindex,inplace=True) print(newDf,'n',data)
None fru_No fru_Num price row1 101 1000 3.56 row2 102 2000 4.20 row3 103 3000 2.50
#创建列索引的映射关系 recolumns = {'fru_No':'col1','fru_Num':'col2','price':'col3'} #用映射重命名水果数据框的行索引和列索引 newDf = data.rename(index=reindex,columns=recolumns) print(newDf)
col1 col2 col3 row1 101 1000 3.56 row2 102 2000 4.20 row3 103 3000 2.50
#用映射重命名水果数据框的单个行索引和单个列索引 newDf = data.rename(index={0:'row1'},columns={'fru_No':'col1'}) print(newDf)
col1 fru_Num price row1 101 1000 3.56 row2 102 2000 4.20 row3 103 3000 2.50
用rename()函数返回一个经过改动的新的Dataframe对象,但原Dataframe对象仍然保持不变,如果要改变调用函数的对象本身,可使用inplace选项,并将其值设置为True
8.6排列和随机抽样 1. 排列利用numpy.random.permutation()函数,可以返回一个序列的随机排列。将此随机排列作为take()函数的参数,通过应用take()函数就可实现按此随机排列来调整Series对象或Dataframe对象各行的顺序。
import numpy as np import pandas as pd #创建Dataframe df = pd.Dataframe(np.arange(12).reshape(4,3)) print(df) #创建随机排列 order = np.random.permutation(4) #通过随机排列调整Dataframe各行顺序 newDf = df.take(order) print(newDf)
0 1 2 0 0 1 2 1 3 4 5 2 6 7 8 3 9 10 11 0 1 2 3 9 10 11 2 6 7 8 1 3 4 5 0 0 1 22.随机采样
随机抽样是指随机从数据中按照一定的行数或者比例抽取数据。随机抽样的函数:
numpy.random.randint(start,end,size)
import numpy as np import pandas as pd #创建Dataframe df = pd.Dataframe(np.arange(12).reshape(4,3)) print(df) #随机抽样 order = np.random.randint(0,len(df),size=3) #通过随机抽样抽取Dataframe中的行 newDf = df.take(order) print(newDf)
0 1 2 0 0 1 2 1 3 4 5 2 6 7 8 3 9 10 11 0 1 2 0 0 1 2 3 9 10 11 3 9 10 118.7 日期转换、日期格式化和日期抽取 1.日期转换
日期转换是指将字符型的日期格式的数据转换成为日期型数据的过程。日期转换函数to_datetime()的语法格式:
pandas.to_datetime(dateString,format)
函数中的参数说明:
dateString:表示字符型时间列。
日期格式化是将时间日期型数据,按照指定格式,转为字符型数据。日期格式化函数:
df_dt.dt.strftime(format)``` 函数中的参数说明: df_dt:表示数据框中时间列名。 format:表示时间日期格式 ### 3、日期抽取 日期抽取是指从日期格式里面抽取出需要的部分属性。 抽取语法: ```df_dt.dt.property``` 参数说明: df_dt:表示数据框中时间列名。 property:表示时间属性 ![](时间属性.jpg) # 实例**见时间日期转换实例** ## 8.8字符串处理 ### 8.8.1内置的字符串的处理方法 #### 1.字符串拆分 split()函数的作用是通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串,其语法格式: ```str.split(str="", num=string.count(str))``` 参数说明: - str:表示字符串的分隔符,默认为所有的空字符,包括空格、换行(n)、制表符(t)等。 - num:表示分割次数。 - 函数返回值:分割后的字符串列表。 ```python str4='#this is string example##'
print(str4)
#this is string example##
print(str4.split(' '))
['#this', 'is', 'string', 'example##']
print(str4.split(' ',str.count(' ')))
['#this', 'is', 'string', 'example##']
print(str4.split(' ',2))
['#this', 'is', 'string example##']2.一处字符串头尾指定字符
strip()函数可用于移除字符串头尾指定的字符(默认为空格)。
str.strip(chars)
该函数中参数chars表示移除字符串头尾指定的字符
函数返回值为移除字符串头尾指定的字符生成的新字符串
stra1='#this is string example##'
print(stra1.strip('#'))
this is string example3.字符串连接
join()函数可以将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串。
'sep'.join(seq)
参数说明:
sep:表示字符串的分隔符,可以为空
seq:表示要连接的元素序列、字符串、元组、字典
函数返回值为一个以分割符sep连接各个元素后生成的字符串。除了jion()函数外,还可以用“+”号将多个字符串连接起来
arr=['a','b','c'] stra2=arr[0]+':'+arr[1]+':'+arr[2] print(stra2) str1=':' str2=arr print(str1.join(str2))
a:b:c a:b:c4、判断是否是子字符串
判断是否是子字符串可以使用in关键字,或者使用find()函数和index()函数判断一个子字符串的位置。 find()函数作用是查找子字符串,若找到返回从0开始的下标值,若找不到返回-1。find()函数返回值是返回子字符串第一次出现的位置的下标值。
格式:str.find(chars)
index()函数作用是在字符串里查找子串第一次出现的位置,类似字符串的find方法,如果查找不到子串,会抛出异常。
格式:str.index(chars)
chars表示要查找的子字符串 函数返回值为返回字符串第一次出现的位置的下标值
stra='#this is string example##' print(stra.find('s')) print(stra.index('s'))
4 4
if 's' in stra: print(stra.find('s'))
4
print(stra.find('o'))
-1
print(stra.index('a'))
185、判断子字符串出现的次数
count()函数可用于统计字符串里某个字符出现的次数,函数的可选参数为字符串搜索的开始与结束位置。函数返回值:返回子字符串在字符串中出现的次数。
格式:str.count(sub,start,end)
参数说明: sub:表示搜索的子字符串 start:表示字符串开始搜索的位置,默认为第一个字符,第一个字符索引值为0 end:表示字符串中结束搜索的位置,默认字符串的最后一个位置 函数返回值为返回子字符串在字符串中出现的次数
strb='#this is string example##' print(strb.count('s')) print(strb.count('s',0,5)) print(strb.count('s',5,len(str)))
3 1 26、替换子字符串
replace()函数可将字符串中的old(旧字符串)替换成new(新字符串),如果指定第三个参数max,则替换不超过max次。
或str.count(sub,start=0,end=len(string))``` old:表示被替换的字符串 new:表示新字符串,用于替换old子字符串 max:可选项,表示替换不超过max次 函数返回值为返回字符串中的old替换成new后生成的新字符串,如果指定第三个参数max,则替换不超过max次 ```python strc = "新浪网www.sina.com" print (strc.replace('com','cn.com')) strd = "#this is string example##" str1 = strd.replace('is', 'was') str2 = str1.replace('#','!',2) print(str1,'n',str2)
新浪网www.sina.cn.com #thwas was string example## !thwas was string example!#8.8.2正则表达式
正则表达式是一个特殊的字符序列,使用正则表达能很方便地在文中查找和匹配字符串模式。Python自1.5版本起增加了re模块,re模块使Python语言拥有全部的正则表达式功能。 单条正则表达式通常被称作regex,它是根据正则表达式语言编写的字符串。Python内置的re模块用于 *** 作regex对象。只有使用import re语句,先导入re模块,才能使用正则表达式。 re模块所提供的函数分为三类:模式匹配、替换和拆分。1、compile()函数
compile()函数用于编译正则表达式,生成一个正则表达式(Pattern)对象,供match()和search()这两个函数使用。
格式:re.compile(pattern[,flags])
参数说明: pattern:表示一个字符串形式的正则表达式 flags:可选,表示匹配模式,如忽略大小写、多行模式等,具体参数见表《正则表达式修饰符-标志(flass)参数》 re.compile()函数返回值为RegexObject对象2、正则表达式对象
正则表达式对象也称为RegexObject对象。 (1)正则表达式修饰符 正则表达式修饰符—标志(flags)参数见下表
(2)正则表达式模式 正则表达式模式是使用特殊的语法来表示一个正则表达式,它的规则: ·正则表达式模式中的字母和数字匹配相同的字符串。 ·多数字母和数字前加一个反斜杠时会拥有不同的含义。 ·标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。 ·反斜杠本身需要使用反斜杠转义。 由于正则表达式通常都包含反斜杠,如模式元素r't',等价于 '\t'。因此,正则表达式中一般都使用r'..'(raw字符串)来定义规则字符串。。 正则表达式模式语法中的特殊元素见下表:
re.match()函数尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
re.match(parrern,string,flags=0)
参数说明: pattern:表示要匹配的正则表达式 string:表示要匹配的字符串 flags:标志位。用于控制正则表达式的匹配方式(例如:区分大小写,多行匹配等,具体见上表) 函数返回值为match()函数从字符串开头开始匹配,匹配成功re.match()函数返回任何一个匹配的对象。如果第一个字符就不匹配,他不会再搜索字符串内部。如果没能找到任何匹配的子字符串,将返回None match()函数可以使用group(num)或groups()匹配对象函数来获取匹配表达式
import re print(re.match(r'(w*)', 'WWW.baidu.com',re.I).span()) # 在起始位置匹配 print(re.match(r'[com]', 'www.baidu.com'))
(0, 3) None
str = "#This is String example##" pattern = re.compile(r'(.*) is (.*)') m_Obj = re.match(pattern, str) if m_Obj: print('m_Obj.group():', m_Obj.group()) print('m_Obj.group(1):', m_Obj.group(1)) print('m_Obj.group(2):', m_Obj.group(2)) else: print('No match!!')
m_Obj.group(): #This is String example## m_Obj.group(1): #This m_Obj.group(2): String example##
str1 = "WWW.sina.com,www.163.com" pattern = re.compile(r'(D*d*)') m_Obj = re.match(pattern, str1) print('m_Obj.group():', m_Obj.group())
m_Obj.group(): WWW.sina.com,www.1634、 re.search()函数
re.search()函数扫描整个字符串并返回第一个成功的匹配。 注意:re.match()函数只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search()函数匹配整个字符串,直到找到一个匹配
格式:re.reach(pattern,string,flags=0)
函数返回值为匹配成功re.search()函数返回一个匹配的对象,否则返回None
import re print(re.search(r'(w*)', 'www.baidu.com').span(),re.M|re.I) # 在起始位置匹配 print(re.search(r'[com]', 'www.baidu.com').span()) # 不在起始位置匹配
(0, 3) re.IGNORECASE|re.MULTILINE (10, 11)
str1 = "www.163.com,www.51job.com" pattern = re.compile(r'd{3}|d{2}') m_Obj = re.search(pattern, str1) print('m_Obj.group():', m_Obj.group())
m_Obj.group(): 163
注意:re.match()函数只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search()函数匹配整个字符串,直到找到一个匹配
5.检索与替换re模块提供了re.sub()函数用于替换字符串中的匹配项。
re.sub(pattern,repl,string,count=0,flages=0)
函数说明: pattern:表示正则表达式中的字符串 repl:表示替换的字符串,也可为一个函数 string:表示要被查找/替换的原始字符串 count:表示匹配后替换的最大次数,默认为0,替换所有
import re str6="#This is String example##"
#删除字符串中的前后#号 sub_str = re.sub(r'^#*|#*$', '', str6) print(sub_str)
This is String example
#将字符串中的空格替换成“-" new_sub_str = re.sub(' ', '-', sub_str) print(new_sub_str)
This-is-String-example
# 删除tel字符串中圆括号 tel = '(0731)22768450' num = re.sub(r'D', '', tel) print('电话号码是:', num)
电话号码是: 0731227684506、findall()函数
findall()函数可在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
pattern.findall(string[,pos[,endpos]])
参数说明: string:表示待匹配字符串 pos:可选参数,表示指定字符串的起始位置,默认为0 endpos:可选参数,表示指定字符串的结束位置,默认字符串的长度
match()函数和search()函数只匹配一次,findall()函数匹配所有项
import re
pattern = re.compile(r'd+')
num1 = pattern.findall('www.163.com,www.51job.com') print(num1)
['163', '51']
num2 = pattern.findall('www.163.com,www.51job.com',0,7) print(num2)
['163']7、re.finditer()函数
finditer()函数与findall()函数类似,可在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern,string,flags=0)
import re #查找字符串的数字,返回一个迭代器 num=re.finditer(r'd+','adhadwg252agywfdqwdqj10w')
for i in num: print (i.group())
252 108、re.split()函数
split()函数按照能够匹配的子串将字符串分割后返回列表。
re.split(pattern,string[,maxsplit=0,flags=0])
参数说明: maxsplit:表示分隔次数,maxsplit=1分隔一次,默认为0,不限制次数
import re
#删除str字符串中的空格 str = "This is String example" str_list = str.split(' ') new_str_list = ''.join(str_list) print(new_str_list)
ThisisStringexample
#将str字符串按空格拆分成列表 str_list = re.split(' ', str) print(str_list)
['This', 'is', 'String', 'example']8.8.3 矢量化的字符串函数
1、cat()字符串连接 cat()函数可实现元素级的字符串连接 *** 作,并可指定分隔符。
格式:Series.str.cat(others=None,sep=None,na_rep=None)
参数说明: others:表示Series、index、Dataframe、np.ndarry(一维或二维)和其他类似字符串的列表 sep:表示连接分隔符,取值string或None,默认为None na_rep:当na_rep为None,序列中的NaN值将被忽略,如果指定,将用该字符串替代 2、split()切分字符串 split()函数可根据分隔符或正则表达式对字符串进行拆分。
格式:Series.str.split(pat=None,n=-1,expand=False)
参数说明: pat:表示要拆分的字符串或正则表达式,如果未指定,则拆分空格 n:表示限制输出中的分割数,无、0和-1将被解释为返回所有拆分 expand:将拆分的字符串展开为单独的列,如果为True,则返回Dataframe/MultiIndex扩展维度;如果为False,则返回包含字符串列表的Series/Index 3. get()获取指定位置的字符串 get()函数可获取各元素的第i个字符。
格式:Series.str.get(i)
import numpy as np import pandas as pd
#1 cat() s = pd.Series(['a', 'b', np.nan, 'd']) print(s.str.cat(['A', 'B', 'C', 'D'], sep=',')) print(s.str.cat(['A', 'B', 'C', 'D'], sep=',', na_rep='-'))
0 a,A 1 b,B 2 NaN 3 d,D dtype: object 0 a,A 1 b,B 2 -,C 3 d,D dtype: object
#2 split() s = pd.Series(["this is good text", "but this is even better"]) print(s.str.split("is", n=1, expand=True))
0 1 0 th is good text 1 but th is even better
#3 get() s = pd.Series(["String", (1, 2, 3), ["a", "b", "c"], 123, -456, {1:"Hello", "2":"World"}]) print(s.str.get(1))
0 t 1 2 2 b 3 NaN 4 NaN 5 Hello dtype: object
除了cat()、split()和get()函数外,Series类的str自带的其它函数,即矢量化的字符串函数见表8-6,其函数语法格式是Series.str.函数名(参数)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)