有没有比for循环和if语句更快的方法来查找python中另一个点的最近点?

code_to_joy:

是否有更快的方法(在带CPU的Python中)与下面的函数做相同的事情?我使用过For循环和if语句,想知道是否有更快的方法?目前,每100个邮政编码大约需要1分钟才能运行此功能,而我大约有70,000个要通过。

使用的2个数据帧是:

postcode_df 其中包含71,092行和列:

  • 邮政编码,例如“ BL4 7PD”
  • 纬度,例如53.577653
  • 经度例如-2.434136

例如

postcode_df = pd.DataFrame({"Postcode":["SK12 2LH", "SK7 6LQ"],
                                    "Latitude":[53.362549, 53.373812],
                                    "Longitude":[-2.061329, -2.120956]})

air 其中包含421行和列:

  • TubeRef,例如“ ABC01”
  • 纬度,例如53.55108
  • 经度例如-2.396236

例如

air = pd.DataFrame({"TubeRef":["Stkprt35", "Stkprt07", "Stkprt33"],
                                    "Latitude":[53.365085, 53.379502, 53.407510],
                                    "Longitude":[-2.0763, -2.120777, -2.145632]})

该函数循环遍历postcode_df中的每个邮政编码,并且对于每个邮政编码循环遍历每个TubeRef并计算(使用geopy)它们之间的距离,并以距邮政编码最短的距离保存TubeRef。

输出df postcode_nearest_tube_refs包含每个邮政编码最近的试管,并包含以下列:

  • 邮政编码,例如“ BL4 7PD”
  • 最近的空气管,例如“ ABC01
  • 到空气管KM的距离,例如1.035848
# define function to get nearest air quality monitoring tube per postcode
def get_nearest_tubes(constituency_list):
    
    postcodes = []
    nearest_tubes = []
    distances_to_tubes = []
    
    for postcode in postcode_df["Postcode"]:
            closest_tube = ""
            shortest_dist = 500

            postcode_lat = postcode_df.loc[postcode_df["Postcode"]==postcode, "Latitude"]
            postcode_long = postcode_df.loc[postcode_df["Postcode"]==postcode, "Longitude"]
            postcode_coord = (float(postcode_lat), float(postcode_long))


            for tuberef in air["TubeRef"]:
                tube_lat = air.loc[air["TubeRef"]==tuberef, "Latitude"]
                tube_long = air.loc[air["TubeRef"]==tuberef, "Longitude"]
                tube_coord = (float(tube_lat), float(tube_long))

                # calculate distance between postcode and tube
                dist_to_tube = geopy.distance.distance(postcode_coord, tube_coord).km
                if dist_to_tube < shortest_dist:
                    shortest_dist = dist_to_tube
                    closest_tube = str(tuberef)

            # save postcode's tuberef with shortest distance
            postcodes.append(str(postcode))
            nearest_tubes.append(str(closest_tube))
            distances_to_tubes.append(shortest_dist)
            
    # create dataframe of the postcodes, nearest tuberefs and distance
    postcode_nearest_tube_refs = pd.DataFrame({"Postcode":postcodes, 
                                          "Nearest Air Tube":nearest_tubes, 
                                          "Distance to Air Tube KM": distances_to_tubes})

    return postcode_nearest_tube_refs

我正在使用的库是:

import numpy as np
import pandas as pd
# !pip install geopy
import geopy.distance
user3184950:

这里的一个工作示例需要花费几秒钟(<10)。

导入库

import pandas as pd
import numpy as np
from sklearn.neighbors import BallTree
import uuid

我生成一些随机数据,这也需要一秒钟,但是至少我们有一些实际的数量。

np_rand_post = 5 * np.random.random((72000,2))
np_rand_post = np_rand_post + np.array((53.577653, -2.434136))

并将UUID用于伪造的邮政编码

postcode_df = pd.DataFrame( np_rand_post , columns=['lat', 'long'])
postcode_df['postcode'] = [uuid.uuid4().hex[:6] for _ in range(72000)]
postcode_df.head()

我们对空气也是如此

np_rand = 5 * np.random.random((500,2))
np_rand = np_rand + np.array((53.55108, -2.396236))

并再次使用uuid进行伪引用

tube_df = pd.DataFrame( np_rand , columns=['lat', 'long'])
tube_df['ref'] = [uuid.uuid4().hex[:5] for _ in range(500)]
tube_df.head()

将gps值提取为numpy

postcode_gps = postcode_df[["lat", "long"]].values
air_gps = tube_df[["lat", "long"]].values

创建一棵球树

postal_radians =  np.radians(postcode_gps)
air_radians = np.radians(air_gps)

tree = BallTree(air_radians, leaf_size=15, metric='haversine')

查询最接近的第一

distance, index = tree.query(postal_radians, k=1)

请注意,距离不是以KM为单位,您需要先进行转换。

earth_radius = 6371000
distance_in_meters = distance * earth_radius
distance_in_meters

例如用 tube_df.ref[ index[:,0] ]

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有比setTimeout(0)更快的方法来产生Javascript事件循环?

有没有比列出目录中所有文件更快的方法来查找文件?

有没有一种简单的方法来获取for循环中的下一个和上一个值?

在气流中,有没有很好的方法来调用另一个dag的任务?

有没有更好的方法来查找Deedle系列中缺少值的第一个键?

有没有比这更快的方法来从T-SQL中的XML节点提取数据?

有没有一种跨平台的方法来检查stdout是否通过管道传递到Rust中的另一个程序中?

有没有比.Any()更快的方法来查找IEnumerable <T>是否具有任何数据?

有没有比fread()更快的方法来读取大数据?

有没有比这更快的方法来检查pandas列中的字符串?我的循环花了很长时间才能完成

有没有更快的方法来创建一个空数组的元素数组而不使用for循环

有没有一种方法可以使用Java中的Timer类来平滑图形组件从一个点到另一个点的过渡?

有没有比count()更快的方法来计数字符串中不重叠的事件?

有没有一种更快的方法来进行熊猫循环?

有没有一种优雅的方法来检查数组中的哪些元素在另一个容器中?

有没有一种有效的方法来搜索列表,而另一个列表保持列表的顺序呢?

有没有比一堆if语句更好的方法来调用我的方法?

有没有更快的方法来搜索一个numpy数组

有没有更好的方法来做到这一点,

有没有比for循环更好的方法将对象数组的属性添加到另一个数组?

有没有更短的方法来做到这一点?

有没有比 for 循环更快的方法来更改 Pandas 组

有没有比 for 循环更快的方法来对 javascript 中的图像进行阈值处理?

有没有更快的方法来查找列表中的重复模式?

有没有更好的方法来比较一个日期和另一个?

有没有比使用 IIFE 更好的方法来做到这一点?

有没有更好的方法来查找表中的条件最后一个值?

有没有更好的方法来做到这一点?

有没有更好的方法来做到这一点?