我有两个巨大的Pandas数据帧,它们具有基于位置的值,我需要用df2的记录数更新df1['count'],这些记录数与df1中每个点的距离都小于1000m。在
这是我的数据的一个例子,导入熊猫
df1 = lat long valA count
0 123.456 986.54 1 0
1 223.456 886.54 2 0
2 323.456 786.54 3 0
3 423.456 686.54 2 0
4 523.456 586.54 1 0
df2 = lat long valB
0 123.456 986.54 1
1 223.456 886.54 2
2 323.456 786.54 3
3 423.456 686.54 2
4 523.456 586.54 1
实际上,df1有大约1000万行,df2有大约100万行
我用熊猫创建了一个工作嵌套FOR循环数据框()方法,对于较小的测试数据集(df1=1k行和df2=100行)很好地工作,但完整的数据集要成倍地大,根据我的计算,需要几年才能完成。这是我的工作代码。。。在
^{pr2}$df2中的每个点只需计数一次,因为df1中的点是均匀分布的。在一次迭代结束时,他们把希望从2行中删除。我最初也尝试创建merge/join语句,而不是嵌套循环,但没有成功。在
现阶段,如有助于提高效率,我们将不胜感激!在
编辑: 目标是用df2的点数更新df1中的“count”列(如下所示),这些点数是<;1km,并输出到一个新文件中。在
df1 = lat long valA count
0 123.456 986.54 1 3
1 223.456 886.54 2 1
2 323.456 786.54 3 9
3 423.456 686.54 2 2
4 523.456 586.54 1 5
我最近也做过类似的事情,但不是用lat,lon做的,我只需要找到最近的点和它的距离。为此,我使用了scipy.space.cKDTree包装。速度相当快。 cKDTree
我认为在您的例子中,您可以使用查询\u ball_point()函数。在
你应该试试看。在
我经常这样做,我发现了一些最佳实践:
1)尽量使用numpy和numba
2)尽量利用并行化
3)跳过矢量化代码的循环(我们在这里使用带numba的循环来利用并行化)。在
在这个特殊的例子中,我想指出geopy带来的减速。虽然它是一个很好的包,并且可以产生相当精确的距离(与Haversine方法相比),但是它要慢得多(没有考虑实现的原因)。在
每个回路216µs±363 ns(平均值±标准偏差,7次运行,每个回路1000次)
也就是说,在这个时间间隔内,计算1000万x 100万的距离大约需要2160亿秒或60万小时。即使是并行也只能起到这么大的作用。在
因为当点非常接近时,您会感兴趣,所以我建议使用Haversine distance(这在较大距离下不太准确)。在
^{pr2}$每个回路1.85µs±53.9 ns(平均值±标准偏差,7次运行,每次100000次循环)
这已经提高了100倍。但我们可以做得更好。您可能已经注意到我从numba添加的
@vectorize
装饰器。这使得以前标量的Haversine函数可以矢量化并将向量作为输入。我们将在下一步中利用这一点:希望现在有一个数组等于第一组坐标的长度(在您的例子中是1000万)。然后你就可以把它分配给你的数据帧作为你的计数!在
测试时间100000 x 10000:
每个回路2.45 s±73.2 ms(7次运行的平均值±标准偏差,每个回路1次)
不幸的是,这仍然意味着你将看到大约20000秒的东西。{ish使用了一个基于cd2}的机器。在
这是我目前所能做的最好的,祝你好运(同时,第一篇文章,感谢你激励我做出贡献!)在
PS:您还可以研究Dask数组和map_block()函数来并行化这个函数(而不是依赖prange)。如何划分数据可能会影响总的执行时间。在
PPS:1000000 x 100000(比全套小100倍)用了3分钟27秒(207秒),所以缩放看起来是线性的,有点宽容。在
购买力平价:通过简单的纬度差滤波器实现:
相关问题 更多 >
编程相关推荐