Python 如何缩短搜索列表的时间?

Python 如何缩短搜索列表的时间?,python,Python,我试图为数据帧的特定成员更改数据帧上“name”列的值。我试图通过使用相同的名称标记相似的名称来减少len(names),这是通过fuzzyfuzzy完成的。我试图找到一种使用嵌套循环的方法: for name in names: for index in df_faces['Nombre'].index: name2 = df_faces.loc[index,'Nombre'] try: if fu

我试图为数据帧的特定成员更改数据帧上“name”列的值。我试图通过使用相同的名称标记相似的名称来减少
len(names)
,这是通过fuzzyfuzzy完成的。我试图找到一种使用嵌套循环的方法:

for name in names:    
    for index in df_faces['Nombre'].index:
        name2 = df_faces.loc[index,'Nombre']
        try:            
            if fuzz.ratio(name, name2) >90:                
                df_faces.loc[index,'Nombre'] = name      
        except:
            pass
其中名称是一个列表,
df_faces
是一个数据框nxm表,这需要很长时间,因为数据框大约有120万个条目,名称大约有1k

编辑:当我删除异常时会发生什么?我猜有些名称是类型float,我得到了这个错误,并且处于模糊模糊状态,我应该转换数据的类型以删除异常吗

edit2:当我使用check_name(x)函数时,我得到了这个错误,实际上我无法找出是什么错误

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-14-6ce51e3e0802> in <module>
      3     return next(gen) if any(gen) else x
      4 
----> 5 df_faces.Nombre = df_faces.Nombre.apply(lambda x: check_name(x))

~/anaconda3/envs/tf-gpu/lib/python3.6/site-packages/pandas/core/series.py in apply(self, func, convert_dtype, args, **kwds)
   4040             else:
   4041                 values = self.astype(object).values
-> 4042                 mapped = lib.map_infer(values, f, convert=convert_dtype)
   4043 
   4044         if len(mapped) and isinstance(mapped[0], Series):

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-14-6ce51e3e0802> in <lambda>(x)
      3     return next(gen) if any(gen) else x
      4 
----> 5 df_faces.Nombre = df_faces.Nombre.apply(lambda x: check_name(x))

<ipython-input-14-6ce51e3e0802> in check_name(x)
      1 def check_name(x):
      2     gen = (name for name in names if fuzz.ratio(name, x) > 90)
----> 3     return next(gen) if any(gen) else x
      4 
      5 df_faces.Nombre = df_faces.Nombre.apply(lambda x: check_name(x))

StopIteration: 
---------------------------------------------------------------------------
StopIteration回溯(最后一次调用)
在里面
3如果有,返回下一个(gen)或其他x
4.
---->5 df_faces.Nombre=df_faces.Nombre.apply(lambda x:检查名称(x))
应用中的~/anaconda3/envs/tf gpu/lib/python3.6/site-packages/pandas/core/series.py(self、func、convert\u dtype、args、**kwds)
4040其他:
4041 values=self.astype(object.values)
->4042 mapped=lib.map\u expert(值,f,convert=convert\u数据类型)
4043
4044如果len(已映射)和isinstance(已映射[0],系列):
pandas/_libs/lib.pyx在pandas中。_libs.lib.map_infere()
in(x)
3如果有,返回下一个(gen)或其他x
4.
---->5 df_faces.Nombre=df_faces.Nombre.apply(lambda x:检查名称(x))
支票中的姓名(x)
1 def检查_名称(x):
2 gen=(如果fuzz.ratio(name,x)>90,名称中的名称的名称)
---->3如果有,返回下一个(gen)或其他x
4.
5 df_faces.Nombre=df_faces.Nombre.apply(lambda x:检查名称(x))
停止迭代:
尝试以下代码:

def check_name(x):
    return next((name for name in names if fuzz.ratio(name, x) > 90), x)

df_faces.Nombre = df_faces.Nombre.apply(lambda x: check_name(x))
check_name()
函数利用生成器,迭代到第一个值满足条件
fuzz.ratio(name,x)>90
时返回,如果没有匹配项,则返回
x

通过该函数,我们将数据帧上的计算矢量化,并有效地获得所需的结果

我对数万个dataframe元素和名称列表中的几百个元素的实例进行了测试,我发布的解决方案比您在应用程序中提出的代码快6倍左右

解释 算法的瓶颈肯定是由非矢量化造成的。迭代和赋值操作非常慢,这就是为什么尽可能将代码矢量化是一种好的做法

矢量化是对整个数组执行操作的过程。矢量化计算的整个要点是通过将计算移动到高度优化的C代码并利用连续内存块来避免Python级循环

其他建议
您可以保留最常见名称的映射(字典或您认为最合适的名称){key:name\u from_df,value:name\u from_list}。这样,您可以在计算模糊比率之前搜索地图。如果名字在地图上,你将有一个时间O(logm),m是地图的大小。这取决于你为你的问题选择合适的m。

试着编写没有异常的代码,
异常
是代价高昂的操作,肯定会消耗很多时间,而不是通过名称查看df waisethanks为了获得帮助,我编辑了关于异常的问题,现在是关于waise,我在旁边用python搜索它,我仍然不知道你的意思是什么,你介意为我详细说明一下吗?这里对于每个单独的名称,你要通过每个df进行处理,我建议的是对每个数据帧尝试替换名称,然后转到其他df,而不是相反的方向,这将节省您的内存读取时间我正在尝试,它正在工作,我将用时间做一个基准,以查看发生了什么感谢帮助我尝试了一下,但我遇到了一个错误,我不明白为什么会这样,我还根据这些信息编辑了问题,希望您能帮助我理解为什么这是我在复制和粘贴
check\u name()
函数时的错误。我已经更正了答案,现在它应该可以正常工作了。我还对答案添加了一些注释。