代码之家  ›  专栏  ›  技术社区  ›  seanysull

将字符串中除最后出现的字符外的所有字符替换为熊猫

  •  9
  • seanysull  · 技术社区  · 8 年前

    使用Pandas删除字符串中除最后一个句点以外的所有句点,如下所示:

    s = pd.Series(['1.234.5','123.5','2.345.6','678.9'])
    counts = s.str.count('\.')
    target = counts==2
    target
    0     True
    1    False
    2     True
    3    False
    dtype: bool
    
    s = s[target].str.replace('\.','',1)
    s
    0    1234.5
    2    2345.6
    dtype: object
    

    然而,我期望的输出是:

    0    1234.5
    1    123.5
    2    2345.6
    3    678.9
    dtype: object
    

    replace命令和mask目标似乎正在删除未替换的值,我看不出如何解决这个问题。

    2 回复  |  直到 7 年前
        1
  •  9
  •   cs95 abhishek58g    7 年前

    基于Regex的 str.replace

    此正则表达式模式具有 str.replace 应该做得很好。

    s.str.replace(r'\.(?=.*?\.)', '')
    
    0    1234.5
    1     123.5
    2    2345.6
    3     678.9
    dtype: object
    

    这个想法是,只要有更多的字符需要替换,就要不断替换。下面是所用正则表达式的分解。

    \.     # '.'
    (?=    # positive lookahead
    .*?    # match anything
    \.     # look for '.'
    )
    

    玩得开心 np.vectorize

    如果要使用 count ,这不是不可能的,但这是一个挑战。您可以使用 np。矢量化 . 首先,定义一个函数,

    def foo(r, c):
        return r.replace('.', '', c)
    

    矢量化,

    v = np.vectorize(foo)
    

    现在,调用函数 v ,通过 s 以及要替换的计数。

    pd.Series(v(s, s.str.count(r'\.') - 1))
    
    0    1234.5
    1     123.5
    2    2345.6
    3     678.9
    dtype: object
    

    请记住,这基本上是一个美化的循环。


    循环/列表理解

    python等效于 vectorize 可能是,

    r = []
    for x, y in zip(s, s.str.count(r'\.') - 1):
        r.append(x.replace('.', '', y))
    
    pd.Series(r)
    
    0    1234.5
    1     123.5
    2    2345.6
    3     678.9
    dtype: object
    

    或者,使用列表理解:

    pd.Series([x.replace('.', '', y) for x, y in zip(s, s.str.count(r'\.') - 1)])
    
    0    1234.5
    1     123.5
    2    2345.6
    3     678.9
    dtype: object
    
        2
  •  0
  •   Stop harming Monica    8 年前

    您希望替换遮罩的项目,并保持其余项目不变。这就是 Series.where 是,但它会替换未屏蔽的值,因此需要对屏蔽求反。

    s.where(~target, s.str.replace('\.','',1))
    

    或者,您可以通过指定遮罩值来进行适当的更改,这可能更便宜,但具有破坏性。

    s[target] = s[target].str.replace('\.','',1)