我有一个数据框:
{'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
这是必要的,以确保特殊字符按字面意思表示。
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] 删除。
我来说两句