pandas Series.replace和Series.str.replace有什么区别?

bq9c1y66  于 2023-05-05  发布在  其他
关注(0)|答案(2)|浏览(181)

通常我的任务是对Series或DataFrames列中的数据执行某种替换或替换操作。
例如,给定一系列字符串,

s = pd.Series(['foo', 'another foo bar', 'baz'])

0                foo
1    another foo bar
2                baz
dtype: object

目标是将所有出现的“foo”替换为“bar”,以获得

0                bar
1    another bar bar
2                baz
Name: A, dtype: object

在这一点上,我通常感到困惑,因为我可以使用两个选项来解决这个问题:replacestr.replace。这种困惑源于这样一个事实,即我不确定哪种方法是正确的,或者它们之间的区别(如果有的话)是什么。
replacestr.replace之间的主要区别是什么,使用两者的好处/注意事项是什么?

waxmsbnn

waxmsbnn1#

跳至TLDR;在本答案的底部,简要总结了这些差异。
如果从实用性的Angular 考虑这两种方法,就很容易理解它们之间的区别。

**.str.replace**是一个 * 非常 * 特殊的方法,对 string 数据执行字符串或正则表达式替换。

OTOH,**.replace**更像是一个通用的Swiss Army knife,它可以用 * 任何其他东西 * 替换 * 任何东西 *(是的,这包括字符串和正则表达式)。
考虑下面简单的DataFrame,这将构成我们即将讨论的基础。

# Setup
df = pd.DataFrame({
    'A': ['foo', 'another foo bar', 'baz'],
    'B': [0, 1, 0]
})
df

                 A  B
0              foo  0
1  another foo bar  1
2              baz  0

这两个函数之间的主要区别可以概括为
1.目的
1.用途
1.默认行为

单个字符串列的子串替换使用str.replace,一列或多列的任何常规替换使用replace

文档将str.replace作为一种“简单字符串替换”的方法进行推广,因此当对pandas Series或column执行字符串/正则表达式替换时,这应该是您的首选-将其视为“向量化”等效于python的字符串replace()函数(或更准确地说是re.sub())。

# simple substring replacement
df['A'].str.replace('foo', 'bar', regex=False)

0                bar
1    another bar bar
2                baz
Name: A, dtype: object

# simple regex replacement
df['A'].str.replace('ba.', 'xyz')

0                foo
1    another foo xyz
2                xyz
Name: A, dtype: object

replace既适用于字符串替换,也适用于非字符串替换。更重要的是,它还意味着**一次处理多个列(如果需要在整个DataFrame中替换值,也可以将replace作为DataFrame方法df.replace()访问)。

# DataFrame-wide replacement
df.replace({'foo': 'bar', 1: -1})

                 A  B
0              bar  0
1  another foo bar -1
2              baz  0

str.replace一次只能替换一件东西。replace允许您执行多个独立的替换,即一次替换多个东西。

只能为str.replace指定单个子字符串或正则表达式模式。repl可以是一个可调用的(请参阅文档),因此有空间使用正则表达式来模拟多个子字符串替换,但这些解决方案充其量是黑客)。
一个常见的pandaic(pandorable,pandonic)模式是使用str.replace删除多个不需要的子字符串,方法是使用正则表达式或管道|来分隔子字符串,替换字符串是''(空字符串)。
replace应该是首选当你有 * 多个独立的 * 形式{'pat1': 'repl1', 'pat2': 'repl2', ...}的替代。有多种指定独立替换的方法(列表、系列、字典等)。参见documentation
为了说明差异,

df['A'].str.replace('foo', 'text1').str.replace('bar', 'text2')

0                  text1
1    another text1 text2
2                    baz
Name: A, dtype: object

会更好地表达为

df['A'].replace({'foo': 'text1', 'bar': 'text2'}, regex=True)

0                  text1
1    another text1 text2
2                    baz
Name: A, dtype: object

在字符串操作的上下文中,str.replace默认启用regex替换。replace仅执行完全匹配,除非使用regex=True开关。
你可以用str.replace做任何事情,你也可以用replace做任何事情。但是,重要的是要注意这两种方法的默认行为的以下差异。
1.子字符串替换-str.replace将替换每个出现的子字符串,默认情况下replace将只执行整个单词匹配

  1. regex replacement -str.replace将第一个参数解释为正则表达式,除非指定regex=Falsereplace正好相反。
    对比之间的区别
df['A'].replace('foo', 'bar')

0                bar
1    another foo bar
2                baz
Name: A, dtype: object

然后呢

df['A'].replace('foo', 'bar', regex=True)

0                bar
1    another bar bar
2                baz
Name: A, dtype: object

另外值得一提的是,当regex=True时,您可以 * 仅 * 执行字符串替换。例如,df.replace({'foo': 'bar', 1: -1}, regex=True)将是无效的。

TLDR;

总结起来,主要的区别是,
1.目的str.replace用于单个字符串列上的子字符串替换,replace用于一个或多个列上的任何常规替换。
1.用法. str.replace一次只能替换一个东西。replace允许您执行多个独立的替换,即一次替换许多东西。
1.默认行为str.replace默认启用regex替换。replace只执行完全匹配,除非使用regex=True开关。

vtwuwzda

vtwuwzda2#

如果您正在比较str.replacereplace,我会假设您只考虑替换字符串。
有两条经验法则可以帮助您(尤其是在使用.apply()lambda时):
1.如果你想一次替换很多东西,可以使用df.replace({dict})。请记住cs95docs中提到的默认值。
1.如果你想使用正则表达式AND * 区分大小写 * 选项,请使用str.replace()lambda x: x.str.replace('^default$', '', regex = True, case = False)
最后需要注意的一点是,inplace参数只在replace函数中可用,而在str.replace中不可用,这可能是代码中的一个决定性因素,特别是如果您正在链接。

相关问题