我有这个数据集;
text num
test one 3.5 and 60 test tow 3.5/60
test one 3/4 test tow 3/4
test one 5.0 test 10 tow 5.0
如果数字与数字匹配,我需要从文本列中删除数字 所以我这样做了:
df['text']=[re.sub('{}'.format(number), '', the_text) for the_text, number in zip(df['text'], df['num'])]
结果变成这样
text num
test one 3.5 and 60 test tow 3.5/60
test one test tow 3/4
test one test 10 tow 5.0
如您所见,除了第一行之外,匹配的数字已被删除,因为它不是完全匹配的。 所以我想使用包含函数匹配或任何类似的东西来匹配文本的一部分。
我希望第一行会变成
test one and test tow
我这样做了,但出现错误:
[re.sub(r"\b{}\b".format(word), "", the_text) for the_text, word in zip(df['text'], word='/'.join([r'{}'.format(words) for words in df['num']]) )]
TypeError: zip() takes no keyword arguments
有什么帮助吗?
最佳答案
你可以使用
df['text'] = df.apply(lambda x: re.sub(r'(?<!\d)(?<!\d\.)(?:{}|{})(?!\.?\d)'.format(re.escape(x['num']), '|'.join([re.escape(l) for l in x['num'].split('/')])), '', x['text']), axis=1)
感谢df.apply
和 axis=1
,我们遍历所有行。
正则表达式是根据 num
中的值动态生成的列并应用于 text
专栏。
r'(?<!\d)(?<!\d\.)(?:{}|{})(?!\.?\d)'.format(re.escape(x['num']), '|'.join([re.escape(l) for l in x['num'].split('/')]))
创建一个正则表达式,如
(?<!\d)(?<!\d\.)(?:3/4|3|4)(?!\.?\d)
与 num
中的两个完整值匹配列和 /
之间的数字分别。
(?<!\d)(?<!\d\.)
是一个后视序列,如果在当前位置的左边有一个数字或一个数字+点,则匹配失败,并且 (?!\.?\d)
如果当前位置的右边有一个数字或一个点 + 数字,则匹配失败,这有效地禁止了较长数字中的数字匹配。
关于python - 根据另一列匹配部分文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62782187/