Python 在数据帧或其他数据结构中查找和寻址的最快方法

Python 在数据帧或其他数据结构中查找和寻址的最快方法,python,dataframe,Python,Dataframe,我有两个大型excel文件(300k和500k)。这两个文件都有地址信息 我需要将它们加载到内存中,然后在500k文件中循环,并检查300k文件中是否存在该地址。如果有或没有,我必须修改地址的某些部分或做其他事情,并生成另一个excel文件 我正在寻找最快的方式找到一个地址匹配公民,街道,街道类型,街道方向和城镇在300k的文件 目前我正在使用: for i in range(len(df)): dfexists = dfsmall.loc[(dfsmall['civic'] == df

我有两个大型excel文件(300k和500k)。这两个文件都有地址信息

我需要将它们加载到内存中,然后在500k文件中循环,并检查300k文件中是否存在该地址。如果有或没有,我必须修改地址的某些部分或做其他事情,并生成另一个excel文件

我正在寻找最快的方式找到一个地址匹配公民,街道,街道类型,街道方向和城镇在300k的文件

目前我正在使用:

for i in range(len(df)):
    dfexists = dfsmall.loc[(dfsmall['civic'] == df.loc[i,'civic']) & (dfsmall['street'] == df.loc[i,'street']) & (dfsmall['streettype'] == df.loc[i,'streettype']) & (dfsmall['streetdirection'] == df.loc[i,'streetdirection']) & (dfsmall['town'] == df.loc[i,'town'])]

#if dfexists has a matching row do something with that row, if not do something else
这是非常缓慢的,我正在寻找方法来加快它

我尝试过其他方法,比如面具,但运气不好,这是迄今为止我发现的最快的方法

问题: 我必须逐行循环,所以我不能只进行数据帧比较,因此我需要知道基于与给定值匹配的多列从数据帧或另一个容器中获取行的最快方法


感谢使用您标识为键的列,您可以为每个数据帧创建由键列中的值组成的元组集,并进行交集以查找公共键,设置差异以查找增量

您还可以创建一个字典,将键映射回数据框中的行索引

检查集合成员资格是O(1),所以做一个交集或差分是O(N)。在字典中查找值是O(1),因此映射回索引是O(N)。所以整个过程是O(N)

一旦有了索引,就可以执行循环或向量化操作,以实现这两种情况所需的更改(公共与增量)。您没有提供关于这些是什么的详细信息,因此下面的示例代码使用伪do_something()函数作为占位符。如果您的操作非常简单,那么向量化的复杂性可能不值得,因为我们已经在python级别执行了O(N)。矢量化在O(N)处渐近相同,但没有python开销(快1000倍左右)


作为pd导入熊猫,作为np导入numpy
#提供df_500k和df_300k
列=['civic'、'street'、'streettype'、'streetdirection'、'town']
list_500k=[df_500k[columns]中的行的元组(行)。values.tolist()]
索引映射500k=dict(zip(列表500k,df 500k.索引))
set_500k=set(列表_500k)
del list_500k
set_300k=set(df_300k[列]中的行的元组(行)。value.tolist()
#编辑:也许这个循环更清楚地表明一次只处理一个地址
对于行索引,在索引映射500k.items()中输入地址键:
如果地址键在set_300k中:
#地址在两个文件中
df_row=df_500k.iloc[行索引:]
#在这种情况下,你想怎么做就怎么做
其他:
#地址不在300k文件中
df_row=df_500k.iloc[行索引:]
#在这种情况下,你想怎么做就怎么做
如上所述,作为上一个循环的替代方法,您可以采取矢量化方法,这取决于您的处理有多复杂或简单,以及它是否会成为比上面的set/dict操作更严重的瓶颈,这些操作总体上是O(N)的python开销

index\u in\u common=np.数组([index\u map\u 500k[key]用于键入(set\u 500k和set\u 300k)])
做一些矢量化的事情(df\U 500k,索引\U公共)
索引\u delta=np.数组([index\u map\u 500k[key]用于键入(set\u 500k-set\u 300k)])
做些什么?做些别的?矢量化(df?500k,指数?增量)

您可能可以用您关心的所有列创建一个多索引,并进行内部连接。如何为300k文件创建一组元组,然后逐个检查500k文件?检查一组中的值是O(1).所以,它应该会加快查找速度。从我读到的内容来看,创建元组更快,但访问列表更快,那么300k作为列表的一个会更快吗?循环检查每行是否比df.loc快?谢谢你的回答。除非我弄错了,否则我不相信这能解决我的问题,因为我一次只需要找到一个地址,p处理它。根据处理情况,我可以通过稍微更改参数再次查找该地址etc@Pearl我相信这确实解决了你的问题。它将500k文件中的每个地址分为两堆——与300k相同的地址和与300k不相同的地址。然后,它一次处理一个地址,就像你问的那样。如果你如果需要再次查找该地址,您可以通过其键查找该地址。我想您是说您不能使用矢量化方法,这很好-无论如何,我将其列为可选方法。@Pearl这是一种一次一件处理每件事情的有效方法。您可以在O(1)中按地址查找任何一行并检查该地址是否存在于O(1)中的另一个文件中。实际的循环可能会因您想执行的操作而有所不同。我无法帮助您,因为您没有说明每行要执行的操作。@Pearl似乎无法说服您。我编辑了上面示例的最后一部分,希望能够更好地说明如何一次处理一个地址nd使您能够灵活地快速查找数据帧的行,并检查地址是否存在于300k文件中。很抱歉,我不在。我刚刚测试了这个,它非常快,但是它会引入唯一的行。因此,例如,如果我只是验证城镇,并且有许多地址与同一城镇,它只会在上验证它ce.在我的数据集中,我将有许多行具有相同的地址,但需要从行中获取其他信息,用于#做你想做的事情区域,如果这有意义的话?