我有一个数据框,其中每一行对应一个字符串。我想从这些字符串中删除某些单词 - 这是我使用 lambda 函数执行此操作的方法:
def remove_words(s):
return s.apply(lambda x: [x for x in x if x not in ["name", "is", "m"]])
s = pd.DataFrame({"s":["Hi my name is Joe", "Hi my name is Hannah", "Hi my name is Brian"]})
remove_words(s.s)
这不会产生正确的结果,因为它从所有单词中删除了 m:
0 [H, i, , y, , n, a, e, , i, s, , J, o, e]
1 [H, i, , y, , n, a, e, , i, s, , H, a, n, ...
2 [H, i, , y, , n, a, e, , i, s, , B, r, i, ...
Name: s, dtype: object
然而,我想要的结果是
0 ["Hi my Joe"]
1 ["Hi my Hannah"]
2 ["Hi my Brian"]
Name: s, dtype: object
- 因此它应该只删除一个
m,如果它是字符串中的一个单独的字母。是否可以使用 lambda 执行此操作?
使用正则表达式时请看这个反例:
regex = '|'.join((' %s ' % word for word in ["in", "out", "between"]))
test = pd.DataFrame({"s": ["hello in out between inner in"]})
test.s.str.replace(regex, " ")
这不会清除所有 out 或 in
0 hello out inner in
Name: s, dtype: object
请您参考如下方法:
使用正则表达式 re.sub
import re
# construct the regex pattern
words = ['name', 'is']
pattern = re.compile(r'\b({})\b'.format('|'.join(words)))
# apply the function on the series
s.s.apply(lambda x: re.sub('\s+', ' ', re.sub(pattern, '', x)))
re.sub 被使用了两次,第一次是删除单词,第二次是替换多余的空格。
输出:
0 Hi my Joe
1 Hi my Hannah
2 Hi my Brian
\b 是单词边界的正则表达式模式。 \b(name|is|a)\b 将匹配以下内容,匹配由删除线表示
一朵任何其他名字
如您所见,即使是单个字母的单词也能正确匹配。但是,还有 1 个问题是上述解决方案尚未解决的。
句子末尾的匹配将留下一个空格,该空格不会被 re.sub(r'\s+', ' ',... 清除。所以,它可能还需要 strip 空格。这取决于您的数据
有了这个注释,最终的解决方案就变成了:
s.s.apply(lambda x: re.sub('\s+', ' ', re.sub(pattern, '', x)).strip())
