熊猫中多个字符的矢量化 str.replace

测距者

我有一个数据框:

 {'country': {0: 'Afghanistan?*', 1: 'Albania?*'},
 'region': {0: 'Asia', 1: 'Europe'},
 'subregion': {0: 'Southern Asia', 1: 'Southern Europe'},
 'rate_per_1000': {0: 6.7, 1: 2.1},
 'count': {0: '2,474', 1: '61'},
 'year': {0: 2018, 1: 2020},
 'source': {0: 'NSO', 1: 'NSO'}}

          country  region        subregion  rate_per_1000  count  year source
0   Afghanistan?*    Asia    Southern Asia            6.7  2,474  2018    NSO
1       Albania?*  Europe  Southern Europe            2.1     61  2020    NSO

这里有多个我想摆脱的坏角色。我为 .apply() 制作了一个简短的函数来摆脱它们,但是我正在循环遍历已定义的坏字符列表。这给我带来了不好的代码气味,我认为这个操作可以在某种程度上更加矢量化。这是我尝试过的:

bad_chars = ['?', '*', ',']

def string_cleaner(col):
    if col.dtype == 'object':
        for char in bad_chars:
            col = col.str.replace(f'{char}', '')
        return col

homicide_by_country = homicide_by_country.apply(string_cleaner)
homicide_by_country
        country  region        subregion rate_per_1000 count  year source
0   Afghanistan    Asia    Southern Asia          None  2474  None    NSO
1       Albania  Europe  Southern Europe          None    61  None    NSO

我想要的结果是一种更 Pythonic/pandonic 的技术来实现相同的结果。

编辑:由于某种原因,您可能会注意到我的 rate_per_1000 列变为空白。我还没有解决这个问题,但如果你发现一些明显的东西,我会全神贯注。

拉斐尔

好像你df.replace需要regex=True

import re
>>> df.replace('|'.join(map(re.escape, bad_chars)),'', regex=True)

请注意,这将保持列的相同 dtypes,因此无需担心数字列。

另外,请注意,您需要对正则表达式进行特殊处理,因为?, *etc 是正则表达式中的特殊字符,因此您需要转义这些字符。


更详细一点,只要是特殊字符,re.escape基本上都会\在每个字符前面加一个。bad_chars这是必要的,以确保特殊字符按字面意思表示。

Python 文档中的这个例子为例

The first metacharacter for repeating things that we’ll look at is *. 
* doesn’t match the literal character '*'; 
instead, it specifies that the previous character can be 
matched zero or more times, instead of exactly once.

这意味着如果您只使用df.replace("*", "", regex=True),引擎将解释*为元字符,而不是星号,这会产生奇怪的结果。但是,如果您这样做df.replace("\*", "", regex=True)*则将被解释为星号。“转义”表示添加 a\以指示您的意思是文字字符的此操作。

现在,|也是一个元字符,意思是“加入”,或者"or". 在这里,我们不想逃避管道,因为我们希望用它的正则表达式功能来解释它。

下面的表达式

'|'.join(map(re.escape, bad_chars))

会产生类似的东西

\?|\*|,

这意味着我们想用空字符串替换所有\?and 。\*,

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章