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)