Python 基于另一列匹配部分文本
我有这个数据集Python 基于另一列匹配部分文本,python,regex,pandas,match,Python,Regex,Pandas,Match,我有这个数据集 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 我需要删除文本列中的数字,如果它在num中匹配 所以我做到了: df['text']=[re.sub('{}'.f
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
我需要删除文本列中的数字,如果它在num中匹配
所以我做到了:
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
正如您所看到的,除了第一行之外,已删除匹配的数字,因为它不是完全匹配的。
所以我想使用contains函数match或者类似于匹配文本部分的任何东西
我预计第一排将成为
试一试拖
我已执行此操作,但出现错误:
[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
有什么帮助吗?创建数字列表,并添加
/
nums = '|'.join(df['num'].tolist()).replace('/', '|') + '|/'
nums
'3.5|60|3|4|5.0|/'
然后替换
df['text'].str.replace(nums, '')
0 test one and test tow
1 test one test tow
2 test one test tow
这项工作:
import re
txt='''\
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 tow 5.0'''
for line in txt.splitlines():
m=re.search(r'^(.*?[ \t]{2,}(?=\d))([0-9.\/]+)$', line)
if m:
a,_,b=m.group(2).partition('/')
if re.search(fr'\b{m.group(2)}\b', m.group(1)):
l=len(m.group(1))
s=re.sub(fr'[ ]?\b{m.group(2)}\b', '', m.group(1))
line=s+' '*(l-len(s))+m.group(2)
elif re.search(fr'{a}[^/]+{b}', m.group(1)):
l=len(m.group(1))
s=re.sub(fr'[ ]?\b{a}\b','',m.group(1))
s=re.sub(fr'[ ]?\b{b}\b','',s)
line=s+' '*(l-len(s))+m.group(2)
print(line)
印刷品:
text num
test one and test tow 3.5/60
test one test tow 3/4
test one test tow 5.0
你可以用
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)
分别匹配num
列中的完整值和/
之间的数字
(?是一个查找序列,如果当前位置左侧有一个数字或一个数字+点,则无法匹配,(?!\?\d)
如果当前位置右侧有一个数字或点+数字,则匹配失败,实际上不允许在较长的数字中进行数字匹配。如果您说有错误,请始终发布错误消息。请尝试而不是“{}”。格式化(数字)
(?@WiktorStribiżew不work@JoelFan我确实非常感谢您的示例数据框df=pd.DataFrame({'text':['testone3.5和60测试拖','testone3/4测试拖','testone5.0测试拖'],'num':['3.5/60','3/4','5.0']})
?请注意,
是一个特殊的regex元字符,5.0
将匹配50
、5+0
等等。您需要对其进行转义。此外,没有任何边界,您将有可能替换43
中的3
。我希望传递num列,以便每一行都匹配文本中的同一行column@WiktorStribiżew如果文本中有任何其他数字不匹配则不会删除
(?<!\d)(?<!\d\.)(?:3/4|3|4)(?!\.?\d)