我需要比较两个评分单词列表(新单词和旧单词(,以找到新列表上不在旧列表上的单词(忽略单词分数(,并返回一个新单词的Python列表(带分数(。输入列表的格式如下:
new = ['RED;25','BLUE;30','YELLOW;50','GREEN;10']
old = ['GREEN;50','YELLOW;50','PURPLE;50']
并且,输出列表需要具有相同的格式。我使用NumPy开发的代码是:
import numpy as np
def find_new_words(new, old):
n, o = np.char.array(new), np.char.array(old)
w_n = np.char.array([i[0:i.find(';')] for i in new])
w_o = np.char.array([i[0:i.find(';')] for i in old])
ans = [n[np.char.find(i, w_n) == 0] for i in np.setdiff1d(w_n, w_o)]
lst = [i for sublist in np.array(ans).tolist() for i in sublist]
return lst
返回正确答案:
['BLUE;30', 'RED;25']
用于上面显示的示例列表。
我遇到的问题是,我的列表有数以万计的条目,这个功能需要很长时间才能处理(对于每个条目约为50000个的新旧列表,大约需要8分钟,这太荒谬了(。有没有想过我该如何加快速度?看起来我只是做了太多不必要的重复循环。我相信还有一种更像Python(NumPonic??(的方法可以做到这一点。
提前感谢!
重写函数以使用列表而不是numpy:
def find_wlist(new, old):
w_n = [i[0:i.find(';')] for i in new]
w_o = [i[0:i.find(';')] for i in old]
d = set(w_n).difference(set(w_o))
lst = [x for x,z in zip(new, w_n) if z in d]
return lst
In [367]: find_wlist(new, old)
Out[367]: ['RED;25', 'BLUE;30']
顺序不同,但结果相同。
In [368]: timeit find_new_words(new, old)
235 µs ± 2.11 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [369]: timeit find_wlist(new, old)
4.61 µs ± 127 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
numpy
在处理字符串时没有提供太多性能优势(如果有的话(,尤其是不匹配这样的操作。