这是我的情况:
我有一个产品名称列表,例如:
BLUEAPPLE, GREENBUTTON20, 400100DUCK20
(len = 9000)
以及官方商品名称列表,例如:
BLUEAPPLE, GREENBUTTON, 100DUCK
。 (len = 2700)
由于我要对产品(商品)应用模糊字符串匹配,因此我想从产品名称中去除不必要的数字,但要保留正式商品名称中表示的数字。
我想出了一个解决方案,但问题是它非常运行缓慢。
def remove_nums(product):
if bool(re.search('\d'), product):
for item in item_nums_list:
if item in product_name:
substrings = [u for x in product_name.split(item) for u in (x, item)][:-1]
no_num_list = [re.sub('(\d+)', '', substring) if substring not in item else substring for substring in substrings]
return ''.join(no_num_list)
return re.sub('(\d+)', '', product)
else:
return product
示例:
product_name = '400100DUCK20'
item = '100DUCK'
substrings = ['400','100DUCK','20']
no_num_list = ['','100OG','']
returns '100DUCK'
此功能已映射,因此可以遍历产品列表中的每个产品。
我一直在试图找到一种在这里使用lambda的方法,映射,应用等,但是我无法完全解决。用直线列表或熊猫来完成我尝试做的事情的最有效的方法是什么?另外,我从postgres数据库中获得这些产品和产品列表,因此,如果您认为在psql中进行操作会更快,那我就走这条路线。
答案 0 :(得分:1)
difflib.get_close_matches()
至少将帮助清理您的代码,并且可能会更快地运行。
import difflib
p_names = ['BLUEAPPLE', 'GREENBUTTON20', '400100DUCK20']
i_names = ['BLUEAPPLE', 'GREENBUTTON', '100DUCK']
for p in p_names:
print(difflib.get_close_matches(p, i_names))
>>>
['BLUEAPPLE']
['GREENBUTTON']
['100DUCK']
>>>
仍然会有很多比较,它必须将p_names中的每个字符串与i_names中的每个字符串进行匹配。
类似于使用正则表达式查找匹配项的方法:
import re
for p in p_names:
for i in i_names:
if re.search(i, p):
print(i)
# stop looking
break
答案 1 :(得分:1)
尝试一下:
def remove_nums(product):
if re.search('\d', product):
for item in item_nums_list:
if item in product:
return item
return re.sub('(\d+)', '', product)
else:
return product
此外,请确保您使用的是普通的python解释器。 IPython和其他具有调试功能的解释器比常规解释器慢很多。
您可能想考虑先进行一些设置操作。这是一个小例子:
product_set = set(product_list)
item_number_set = set(item_number_list)
# these are the ones that match straight away
product_matches = product_set & item_number_set
# now we can search through the substrings of ones that don't match
non_matches = product_set - item_number_set
for product in non_matches:
for item_number in item_number_set:
if item_number in product:
product_matches.add(product)
break
# product_matches is now a set of all unique codes contained in both lists by "fuzzy match"
print(product_matches)
您可能会失去它们出现的顺序,但是也许您可以找到一种方法来对其进行修改以供使用。