当前位置: 首页 > 面试题库 >

如何根据最接近的匹配从另一个有效地替换大型数据框(100k +行)中的值?

慎建本
2023-03-14
问题内容

因此,我使用莱文郡距离来查找最接近的匹配项,并使用此答案作为基础来替换大型数据框中的许多值:

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

   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

   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


问题答案:

因此,我采取了一些措施来提高速度,并使速度提高了近4800倍。

在此处发布内容可以使处理熊猫上任何CPU密集型任务的性能降低的人受益:

  1. 我没有像问题中那样一次替换掉所有内容,而是制作了一个替换字典,用每个数据帧中的唯一值进行替换,这使它从永远花费(我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)

  2. 我使用了一个基于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倍。

  3. 然后,我通过并行性立即利用了所有核心。为此,我经历了多种选择,例如多处理和线程处理,但是它们都没有提供与modin.pandas一样快的比较结果。它的变化很小(只需输入一行即可modin.pands as pd代替import pandas as pd),并且运行优雅。它使以前的运行速度提高了约4倍。

这样一来,总的加速比达到了4800倍,整个过程瞬间就实现了。



 类似资料:
  • 问题内容: 我有一个数组和一个引用数组。的大小至少等于。例如 实际上是在指定时间信号中的峰值位置,并且包含稍后时间的峰值位置。但是某些元素实际上是不是我想要的峰(可能是由于噪声等),我想找到“真正的”一个基础。中的“真实”元素应与中的元素接近,在上面给出的示例中,中的“真实”元素应为。在这个例子中应该很明显不是我们想要的,因为它们与B中的任何元素都相去甚远。如何在python / matlab中以

  • 问题内容: 我有两个数据框,第一个有1000行,看起来像: 该列具有不同的值,有时会重复,但通常大约有50个唯一值。 第二个数据框包含所有这50个唯一值(50行)以及与这些值关联的酒店: 我的目标是用第二个数据帧的列的相应值替换第一个数据帧的列中的值,或者用相应的值创建该列。当我尝试通过像 我有一个错误,即数据帧的大小不相等,因此无法进行比较 问题答案: 如果将索引设置为另一个df上的“组”列,则

  • 问题内容: 注意:为简单起见,我使用一个玩具示例,因为复制/粘贴数据帧在堆栈溢出中很困难(请让我知道是否有简便的方法来执行此操作)。 有没有一种方法可以将一个数据帧中的值合并到另一个数据帧中而无需获取_X,_Y列?我希望一列中的值替换另一列中的所有零值。 在上一篇文章中,我尝试了Combine_First和dropna(),但是这些都做不到。 我想用df2中的值替换df1中的零。此外,我希望根据d

  • 我有两个数据框: 我希望对 df2 执行逐行运算,我将 df2 中的每一列与 df1 中的相应行相乘,然后执行求和。 例如,对于df2的第1行,我希望计算: 同时排除不匹配(df1中的行)或具有NAs的列。 我在df1中有几千行,在df2中有数千行和列。 非常感谢任何帮助!! PS。我在Perl中使用哈希实现了这一点,并使用system()调用在Rmarkdown文档中执行这些计算。为了保持它的完

  • 问题内容: 我有2个数据框,一个命名为USERS,另一个命名为EXCLUDE。他们两个都有一个名为“电子邮件”的字段。 基本上,我要删除EXERSUDE中包含电子邮件的USERS中的每一行。 我该怎么做? 问题答案: 您可以将和条件一起使用,通过以下方式反转布尔值: 另一个解决方案:

  • 问题内容: 我要执行的操作类似于合并。例如,通过合并,我们得到一个数据帧,其中包含第一个AND第二个数据帧中存在的行。通过合并,我们得到一个数据帧,该数据帧在第一个或第二个数据帧中都存在。 我需要的是一个数据帧,其中包含第一个数据帧中存在的行而第二个数据帧中不存在的行?有快速而优雅的方法吗? 问题答案: 如下所示呢? 只要有一个非关键的通用命名列,就可以让在sufffexes上执行的工作(如果没有