替换除数据帧中最后一个字符之外的所有字符

sea*_*ull 9 python regex string pandas

使用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
Run Code Online (Sandbox Code Playgroud)

然而,我想要的输出是:

0    1234.5
1    123.5
2    2345.6
3    678.9
dtype: object
Run Code Online (Sandbox Code Playgroud)

替换命令以及掩码目标似乎正在删除未替换的值,我无法看到如何解决这个问题.

cs9*_*s95 8

选项1
这个正则表达式模式str.replace应该做得很好.

s.str.replace(r'\.(?=.*?\.)', '')

0    1234.5
1     123.5
2    2345.6
3     678.9
dtype: object
Run Code Online (Sandbox Code Playgroud)

这个想法是,只要有更多的字符要替换,继续更换.这是使用的正则表达式的细分 -

\.     # '.'
(?=    # positive lookahead
.*?    # match anything
\.     # look for '.'
)
Run Code Online (Sandbox Code Playgroud)

选项2
如果你想使用str.replace它,这不是不可能的,但这是一个挑战.你可以使这更容易np.vectorize.首先,定义一个函数 -

def foo(r, c):
    return r.replace('.', '', c)
Run Code Online (Sandbox Code Playgroud)

矢量化 -

v = np.vectorize(foo)
Run Code Online (Sandbox Code Playgroud)

现在,调用函数count,传递np.vectorize和计数替换 -

pd.Series(v(s, s.str.count(r'\.') - 1))

0    1234.5
1     123.5
2    2345.6
3     678.9
dtype: object
Run Code Online (Sandbox Code Playgroud)

请记住,这基本上是一个美化的循环.相当于它的python类似于 -

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
Run Code Online (Sandbox Code Playgroud)

或者,使用列表理解 -

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
Run Code Online (Sandbox Code Playgroud)