赞
踩
在Pandas中做数据处理,经常使用.replace()与.str.replace()方法来进行数据替换,本文介绍两种方法适用的对象,其中对于Series数据类型,它是一个由一维数组表示的DataFrame列,而.replace和.str.replace是Series对象的两种方法,虽然它们的名称相似,并且都用于替换Series的值,但实际上它们之间存在不同之外。
函数语法:
str.replace(old,new,count)
参数说明:
参数 | 描述 |
---|---|
old | 不可省略参数,string,被替换的字符串 |
new | 不可省略参数,string,替换后的字符串 |
count | 可选参数,int,替换不超过max次。 |
举例1: 省略count时,匹配到的所有old字符串都会被替换成new字符串。
testStr = 'visit CSDN website'
#省略count时,匹配到的所有old字符串都会被替换成new字符串。
result = testStr.replace('website','!')
print('String after replacing:', result)
运行结果:
举例2: count值出现几次即代表replace()替换字符串的次数
testStr = 'visit CSDN website website website'
#count=2时,replace替换2次
result = testStr.replace('website','!',2)
print('String after replacing:', result)
#当count大于old字符串出现次数,即全部替换,此时count参数出现没有任何意义。
运行结果:
testStr = 'visit CSDN website website website'
#当count为负数,count参数不作用。replace()方法将全部old_str替换为new_str。
result = testStr.replace('website','!',-1)
print('String after replacing:', result)
运行结果:
DataFrame.replace()函数语法:
DataFrame.replace(to_replace=None, value=_NoDefault.no_default, *,inplace=False, limit=None, regex=False, method=_NoDefault.no_default)
Series.replace()函数语法:
Series.replace(to_replace=None, value=_NoDefault.no_default, *,inplace=False, limit=None, regex=False, method=_NoDefault.no_default)
在Pandas中,Series是一个由一维数组表示的DataFrame列。Series.replace()与DataFrame.replace()方法参数一致。而Series对象的有.replace()和.str.replace()两种方法。虽然它们的名称相似,并且都用于替换Series的值,但实际上它们之间存在不同之外,下面会讲到。
参数说明:
参数 | 描述 | 说明 |
---|---|---|
to_replace | 被替换的值 | 字符串、正则表达式、str,正则表达式,数字的列表、字典,默认无。 |
value | 替换后的值 | 标量、字典、列表、str、正则表达式、默认无。 |
inplace | 是否要改变原数据 | 布尔值,默认是False,False是不改变,True是改变。 |
limit | 控制填充次数。 | 整数,默认无。 |
regex | 是否使用正则,False是不使用,True是使用,默认是False。 | 是否翻译to_replace和/或value作为正则表达式。如果这是True然后to_replace必须成为一个字符串。或者,这可以是一个正则表达式或一个列表、字典或正则表达式数组,在这种情况下to_replace一定是None。 |
method | 填充方式,pad,ffill,bfill分别是向前,向前,向后填充。 | 当to_replace 是标量、列表或元组且 value 是 None 时,默认使用的替换方法为pad。 |
举例1: 对DataFrame进行替换。
import pandas as pd data = pd.DataFrame({'A': [1, 80, 4], 'B': [9, 80, 5], 'C': ['foo','another foo bar','baz']}) print("data:\n", data) print("data.dtypes:\n", data.dtypes) #用dict进行单值、多值填充 data.replace({1,80},{'a','b'}) #1被a替换,80被b替换。 data.replace({1:'a',9:'b'}) #另一种写法,1被a替换,9被b替换。推荐这种写法。 data.replace({'A':1,'B':9},100) #A列的1与B列的9都被替换为100。 data.replace({'A':{1:10, 4:40}}) #A列的1被替换为10,4被替换为40。 #用list进行单值、多值填充 data.replace([1,9],'b') #1,9都被b替换。 data.replace([1,9],[2,10]) #1,9分别被2,10替换。 #替换全部 data.replace(80,8) #某一列或者某几列 data['B'].replace(9,20) #将B列中的9替换成20。 data[['A','B']].replace(80,8) #将A、B列中的9替换成20。 #某一行或者某几行 data.iloc[1].replace(80,8) #第二行的80替换成8。 data.iloc[0:2].replace(80,8) #第一、二行的80替换成8。 #to_replace是正则表达式,regex=True data.replace(r'fo.$','new',regex=True) data.replace({'C':r'fo.$'}, {'C':'new'}, regex=True) #如果regex一个正则表达式或一个列表、字典或正则表达式数组,在这种情况下to_replace一定是None。 data.replace(regex=r'fo.$', value='new') data.replace(regex={r'fo.$':'new', 'baz':'abc'}) data.replace(regex=[r'fo.$','baz'], value='new') #inplace=True,改变原数据 data.replace(80,8,inplace=True) data.iloc[0:2].replace(80,8,inplace=True) #当to_replace是标量、列表或元组且value是 None 时,methond默认使用的替换方法为pad。 data.replace(['foo','baz'])
举例2: 对Series进行替换。
import pandas as pd data = pd.DataFrame({'A': [1, 80, 4], 'B': [9, 80, 5], 'C': ['foo','another foo bar','baz']}) print("data:\n", data) print("data.dtypes:\n", data.dtypes) #用dict进行单值、多值填充 data['C'].replace({'foo':'hello'}) #将C列中的foo替换成hello。 data['C'].replace({'foo':'hello','baz':'bus'}) #将C列中的foo替换成hello,baz替换成bus。 #用list进行单值、多值填充 data['C'].replace(['foo'],['baz'])#将C列中的foo替换成baz。 data['C'].replace(['foo','baz'],'b'))#将C列中的foo和baz替换成b。 data['C'].replace(['foo','baz'],['hello','bus']) #将C列中的foo替换成baz,baz替换成bus。 #某一列或者某几列 data['B'].replace(9,20) #将B列中的9替换成20。 #某一行或者某几行 data.iloc[1].replace(80,8) #第二行的80替换成8。 #to_replace是正则表达式,regex=True data['C'].replace(r'fo.$','new',regex=True) data['C'].replace({r'fo.$':'new'}, regex=True) #如果regex一个正则表达式或一个列表、字典或正则表达式数组,在这种情况下to_replace一定是None。 data['C'].replace(regex=r'fo.$', value='new') data['C'].replace(regex={r'fo.$':'new', 'baz':'abc'}) data['C'].replace(regex=[r'fo.$','baz'], value='new') #inplace=True,改变原数据 data['B'].replace(9,8,inplace=True) data.iloc[1].replace(80,8,inplace=True) #当to_replace是标量、列表或元组且value是 None 时,methond默认使用的替换方法为pad。 data['C'].replace(['foo','baz'])#将C列中的foo替换成hello。
函数语法:
Series.str.replace(pat, repl,n=-1,case=None,flags=0,regex=None)
参数说明:
参数 | 描述 |
---|---|
pat | 要查找的字符串,string,不可省略的参数。 |
repl | 替换的字符串,string,可以调用函数,不可省略的参数。 |
n | 要进行替换的次数,默认全部。 |
case | 是否区分大小写。 |
flags | re模块中的标志。如re.IGNORECASE。 |
regex | 是否设置为正则表达式,False是不使用,True是使用,默认是True。 |
.str.replace() 仅用于字符串匹配和替换,接受两个参数,第一个参数指定要替换的模式,仅限于正则表达式,第二个参数指定要用于替换的字符串。
举例:
import pandas as pd data = pd.DataFrame({'A': ['1', '2', '4'], 'B': ['2023/9/9', '2023/8/8','2023/5/4'], 'C': ['FOO','ANOther foo bar','BAZ']}) print("data:\n", data) print("data.dtypes:\n", data.dtypes) #普通替换 data['C'].str.replace('FOO','foo') #将C列中FOO替换成foo。 #正则表达式的替换 data['B'].str.replace('[/]','-') #预编译好的正则表达式替换 import pandas as pd import re pat=re.compile('[/]') data['B'].str.replace(pat,'-') #函数替换 data['C'].str.replace('[A-Z]',lambda x:x.group().lower()) #将C列中大写字母替换成小写字母。
1、.replace()方法可以用于数字、布尔值和任何可替换的数据类型;而.str.replace()方法仅适用于字符串。
创建测试DataFrame,下面的例子都基于这个DataFrame。
import pandas as pd
data = pd.DataFrame({'A': ['1', '2', '4'],
'B': [9, 80, 5],
'C': ['FOO','ANOther foo bar','BAZ']})
print("data:\n", data)
print("data.dtypes:\n", data.dtypes)
运行结果:
举例1: .replace()方法作用于int64数据类型。
要求:将整个dataframe中数据列B的9替换成20。
data['B'].replace(9,20)
运行结果:
举例2: .str.replace()方法作用于int64数据类型,报错:AttributeError: Can only use .str accessor with string values!。
要求:将整个dataframe中数据列B的9替换成20
data['B'].str.replace(9,20)
运行结果:
我们可以看数据列B是int64数据类型,因此直接使用str.replace() 会报以下错误提示,因为 .str.replace()只针对字符串数据类型 的列有效。
2、.replace()方法可以一次为单个字符串元素(str)、一列(Series)、多个列(DataFrame)工作,如果有需要,可以对整个DataFrame的值进行替换;而.str.serires()方法只能作用于一列(Series)。
创建测试DataFrame,下面的例子都基于这个DataFrame。
import pandas as pd
data = pd.DataFrame({'A': [9, 20, 40],
'B': [9, 80,5],
'C': ['foo','another foo bar','baz']})
print("data:\n", data)
print("data.dtypes:\n", data.dtypes)
运行结果:
举例1: .replace()方法作用于整个DataFrame的值。
要求:将C列中的foo替换成hello,A、B列中9替换成bus。
data.replace({'foo':'hello',9:'bus'}) #将C列中的foo替换成hello,A、B列中9替换成bus。
运行结果:
要求:将整个dataframe中的9替换成90。
data.replace(9,90) #将整个dataframe中的9替换成90
运行结果:
举例2: .replace()方法作用于单个字符串元素(<class ‘str’>),实际上是函数str.replace(old,new,count)。
要求:将C列中第二行元素从80替换成8。
print(type(data['C'].loc[0]))
data['C'].loc[0].replace('foo','abc')
运行结果:
举例3: .replace()方法作用于多列。
要求:将A、B列中的80替换成8。
data[['A','B']].replace(80,8)
运行结果:
举例4: .str.relace()方法作用于整个dataframe、多列、单个字符串元素(<class ‘str’>),都会报错。
要求:将整个dataframe中的9替换成90
data.str.replace('9','90')
报错:
要求:将A、B列中的80替换成8。
data[['A','B']].str.replace(80,8)
报错:
要求:将C列中第二行元素从80替换成8。
data['C'].loc[0].str.replace('foo','abc')
报错:
3、.replace()方法可以一次执行多个独立的替换,.str.replace()方法一次只可以替换一件事。
创建测试DataFrame,下面的例子都基于这个DataFrame。
import pandas as pd
data = pd.DataFrame({'A': ['9', '20', '40'],
'B': ['9', '80','5'],
'C': ['foo','another foo bar','baz']})
print("data:\n", data)
print("data.dtypes:\n", data.dtypes)
运行结果:
举例1: .replace()方法执行多个独立的替换。
要求:将整个dataframe中的数据列C中foo替换成text1,bar替换成text2。
#更好的表达方式
data['C'].replace({'foo': 'text1', 'bar': 'text2'}, regex=True)
data['C'].replace('foo','text1',regex=True).replace('bar','text2'), regex=True)
运行结果:
举例2: .str.replace()方法只一个一个替换,不可以像.replace()方法一样传入字典做多个独立的替换。
要求:将整个dataframe中的数据列C中foo替换成text1,bar替换成text2。
data['C'].str.replace('foo','text1').str.replace('bar','text2')
运行结果:
4、.replace()方法是默认regex=False,.str.replace()方法是默认启用正则表达式替换。
创建测试DataFrame,下面的例子都基于这个DataFrame。
import pandas as pd
data = pd.DataFrame({'A': [9, 20, 40],
'B': [9, 80,5],
'C': ['foo','another foo bar','baz']})
print("data:\n", data)
print("data.dtypes:\n", data.dtypes)
运行结果:
举例1
要求:将字符串foo全部替换字符串text1。
data['C'].replace('foo','text1') #默认情况下,只会执行对foo全字匹配替换。
data['C'].replace('foo','text1',regex=True) #regex=True情况下,每次出现的子字符串foo都会被替换为text1。
data['C'].str.replace('foo','text1') #默认情况下,每次出现的子字符串foo都会被替换为text1。
运行结果1:
运行结果2:
运行结果3:
导入数据及查看数据情况
import os
import pandas as pd
import numpy as np
#读取文件
def read_file(filepath):
os.chdir(os.path.dirname(filepath))
return pd.read_csv(os.path.basename(filepath),encoding='utf-8')
file_pos="F:\\python_test\\data_1.csv"
data_pos=read_file(file_pos)
data_pos
data_pos.dtypes
1、要求: 将2021金额与2022金额的 ¥ 与 , 这两个符号替换为空。
2、实现过程:
def convert_currency(value):
'''
移除不是数字字符 ¥,
'''
new_value=value.replace({',':'','¥':''})
return new_value
#调用函数
a=convert_currency(data_pos['2021金额'])
a
运行结果:
3、发现问题: 使用.replace()无效, 将2021金额与2022金额的 ¥ 与 , 这两个符号并没有替换为空。
4、原因分析: .replace()方法默认情况下只会执行全字匹配,只有regex=True在进行正则表达式替换。
5、解决方案:
def convert_currency(value):
'''
移除不是数字字符 ¥,
'''
new_value=value.replace({',':'','¥':''},regex=True)
return new_value
#调用函数
a=convert_currency(data_pos['2021金额'])
a
运行结果:
注意: 针对上面的解决方案一使用apply调用函数会报错:TypeError: str.replace() takes no keyword arguments。
如下代码
data_pos['2021金额'].apply(convert_currency)
原因: Series使用apply方法后,apply会自动遍历整个Series,将Series分解为一个个元素(元素数据类型跟数据列的数据类型一致)传入函数中。因为data_pos[‘2021金额’]是Series数据类型,apply调用convert_currency()函数,实际上将一个个单独的<class ‘str’>元素调用.replace()方法,会默认为str.replace(old,new,count),并不存在regex这个参数,因此会报错:TypeError: str.replace() takes no keyword arguments。具体分析过程可参考:python报错—为什么用apply方法使用.replace()方法报错TypeError: str.replace() takes no keyword arguments
def convert_currency(value):
'''
移除不是数字字符 ¥,
'''
new_value=value.str.replace(',','').str.replace('¥','')
return new_value
#调用函数
a=convert_currency(data_pos['2021金额'])
a
运行结果:
注意: 针对上面的解决方案二使用apply调用函数会报错:AttributeError: ‘str’ object has no attribute ‘str’。
如下代码
data_pos['2021金额'].apply(convert_currency)
原因: Series使用apply方法后,apply会自动遍历整个Series,将Series分解为一个个元素(元素数据类型跟数据列的数据类型一致)传入函数中。对于使用.str.replace()方法来进行正则替换,.str.replace()只适用于Series对象,不用作用于<class ‘str’>类型,因此会报错AttributeError: ‘str’ object has no attribute ‘str’。具体分析过程可参考:python报错—为什么用apply方法使用.replace()方法报错TypeError: str.replace() takes no keyword arguments
参考文章:
https://blog.csdn.net/m0_62011685/article/details/124716966?ydreferer=aHR0cHM6Ly9jbi5iaW5nLmNvbS8%3D
https://www.cnblogs.com/cgmcoding/p/13362539.html
https://www.coder.work/article/1269173
https://geek-docs.com/pandas/pandas-questions/419_pandas_what_is_the_difference_between_seriesreplace_and_seriesstrreplace.html
https://zhuanlan.zhihu.com/p/108861452
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.str.replace.html
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.replace.html#pandas.DataFrame.replace
https://vimsky.com/examples/usage/python-pandas.Series.replace.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。