因此,我使用莱文郡距离来查找最接近的匹配项,并使用此答案作为基础来替换大型数据框中的许多值:
import operator def levenshteinDistance(s1, s2): if len(s1) > len(s2): s1, s2 = s2, s1 distances = range(len(s1) + 1) for i2, c2 in enumerate(s2): distances_ = [i2+1] for i1, c1 in enumerate(s1): if c1 == c2: distances_.append(distances[i1]) else: distances_.append(1 + min((distances[i1], distances[i1 + 1], distances_[-1]))) distances = distances_ return distances[-1] def closest_match(string, matchings): scores = {} for m in matchings: scores[m] = 1 - levenshteinDistance(string,m) return max(scores.items(), key=operator.itemgetter(1))[0]
因此,在从具有类似大小的另一个大型数据帧(100k +行)中替换许多值时,将永远需要运行:(从最近半小时开始运行!)
results2.products = [closest_match(string, results2.products) if string not in results2.products else string for string in results.products]
有没有办法更有效地做到这一点?我出于相同的目的添加了if-else条件,这样,如果存在直接匹配,就不会涉及任何计算,而这些计算也将产生相同的结果。
results:
results
products 0, pizza 1, ketchup 2, salami 3, anchovy 4, pepperoni 5, marinara 6, olive 7, sausage 8, cheese 9, bbq sauce 10, stuffed crust
results2:
results2
products 0, salaaaami 1, kechap 2, lives 3, ppprn 4, pizzas 5, marinara 6, sauce de bbq 7, marinara sauce 8, chease 9, sausages 10, crust should be stuffed
我希望将值results2替换为最接近的匹配项results
在此处发布内容可以使处理熊猫上任何CPU密集型任务的性能降低的人受益:
我没有像问题中那样一次替换掉所有内容,而是制作了一个替换字典,用每个数据帧中的唯一值进行替换,这使它从永远花费(我2小时后停止)到2分钟,因为有很多重复价值观。多数民众赞成在60倍加速:
replacements = {string: closest_match(string, results2.products.unique()) if string not in results2.products.unique() else string for string in results.products.unique()}
results.replace({‘products’:replacements}, inplace = True)
我使用了一个基于C的实现,它利用了:editdistance库来计算levenshtein距离。在研究中,我发现许多这样的任务都具有基于C的实现,例如矩阵乘法和搜索算法等都可以轻松获得。此外,您始终可以使用C编写模块并在python中使用它。 editdistance.eval('banana', 'bahama')仅1.71 µs ± 289 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)与我定义的函数levenshteinDistance('banana', 'bahama')进行了比较,后者34.4 µs ± 4.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)的速度提高了20倍。
editdistance.eval('banana', 'bahama')
1.71 µs ± 289 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
levenshteinDistance('banana', 'bahama')
34.4 µs ± 4.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
然后,我通过并行性立即利用了所有核心。为此,我经历了多种选择,例如多处理和线程处理,但是它们都没有提供与modin.pandas一样快的比较结果。它的变化很小(只需输入一行即可modin.pands as pd代替import pandas as pd),并且运行优雅。它使以前的运行速度提高了约4倍。
modin.pands as pd
import pandas as pd
这样一来,总的加速比达到了4800倍,整个过程瞬间就实现了。