【问题标题】:What is the difference between Series.replace and Series.str.replace?Series.replace 和 Series.str.replace 有什么区别?
【发布时间】:2019-10-30 16:14:26
【问题描述】:

我的任务通常是对 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 之间的主要区别是什么,使用它们有什么好处/注意事项?

【问题讨论】:

    标签: python pandas replace


    【解决方案1】:

    跳到 TLDR;在这个答案的底部简要总结 差异。

    如果您从实用性的角度考虑这两种方法,就很容易理解它们的区别。

    .str.replace 是一种具有 非常 特定目的的方法 - 对 string 数据执行字符串或正则表达式替换。

    OTOH,.replace 更像是一个通用的 Swiss Army knife,它可以用 anything else 替换 anything(是的,这包括字符串和正则表达式)。

    考虑下面的简单 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. 目的
    2. 用法
    3. 默认行为

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

    文档市场 str.replace 作为“简单字符串替换”的方法,因此在对 pandas 系列或列执行字符串/正则表达式替换时,这应该是您的首选——将其视为相当于 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 可以是可调用的(请参阅文档),因此可以使用正则表达式来发挥创意,以在某种程度上模拟多个子字符串替换,但这些解决方案充其量只是 hacky)。

    一种常见的 pandaic(pandorable,pandonic)模式是使用 str.replace 来删除多个不需要的子字符串,方法是使用正则表达式 OR 管道 | 管道分隔子字符串,替换字符串为 ''(空字符串) .

    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 默认启用正则表达式替换。 replace 只执行完全匹配,除非使用 regex=True 开关。

    您对str.replace 所做的一切,您也可以对replace 进行。但是,请务必注意两种方法的默认行为的以下差异。

    1. 子字符串替换 - str.replace 将替换每个出现的子字符串,replace 默认只执行整个单词匹配
    2. 正则表达式替换 - 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 用于一个或多个上的任何一般替换 列。

    2. 用法str.replace 一次可以替换一件事。 replace 可以让你执行多个独立的替换,即替换很多东西 一次。

    3. 默认行为str.replace 默认启用正则表达式替换。 replace 只执行完全匹配,除非使用 regex=True 开关。

    【讨论】:

    • 很好的解释!我喜欢 Dataframe.replace 的一点是它是一种 DataFrame 级别的方法,允许跨列替换。说有一个'?在整个 df 中代替 NaN。
    • @Vaishali 是的,replace 非常方便!虽然我在这里唯一没有提到的是它的性能方面,因为我认为它会保持简单。当我有更多时间时,我将对此进行扩展。 :)
    • 需要注意的一点是,从 pandas 1.2.0(2020 年 12 月 26 日)开始,发行说明指出“Series.str.replace() 的正则表达式的默认值将从 True 更改为在未来的版本中是错误的。”因此,如果您使用 str.replace,您可能需要手动包含 regex=True。 pandas.pydata.org/docs/whatsnew/v1.2.0.html#deprecationse
    【解决方案2】:

    如果您将str.replacereplace 进行比较,我会假设您只想替换字符串。

    有帮助的两条经验法则(尤其是在使用 .apply()lambda 时)是:

    1. 如果您想一次替换很多东西,请使用df.replace({dict})。请记住cs95docs 中提到的默认值。
    2. 如果您想使用正则表达式和 区分大小写 选项,请使用 str.replace()lambda x: x.str.replace('^default$', '', regex = True, case = False)

    最后要注意的是,inplace 参数仅在 replace 函数中可用,而在 str.replace 中不可用,这可能是代码中的决定因素,尤其是在链接时。

    【讨论】:

      猜你喜欢
      • 2020-11-06
      • 2010-10-02
      • 2011-12-12
      • 2010-09-16
      • 2012-03-14
      • 2012-02-06
      • 2011-02-25
      • 2011-11-22
      • 2015-03-26
      相关资源
      最近更新 更多