我有一个包含超过 500 万行地理位置数据的两列(纬度、经度)的 csv 文件。我需要识别不在列表中任何其他点 5 英里范围内的点,并将所有内容输出回另一个具有额外列 ( CloseToAnotherPoint
) 的 CSV,即True
是否有另一个点在 5 英里范围内,False
如果有不。
这是我当前使用的解决方案geopy
(不进行任何网络调用,仅使用该函数计算距离):
from geopy.point import Point
from geopy.distance import vincenty
import csv
class CustomGeoPoint(object):
def __init__(self, latitude, longitude):
self.location = Point(latitude, longitude)
self.close_to_another_point = False
try:
output = open('output.csv','w')
writer = csv.writer(output, delimiter = ',', quoting=csv.QUOTE_ALL)
writer.writerow(['Latitude', 'Longitude', 'CloseToAnotherPoint'])
# 5 miles
close_limit = 5
geo_points = []
with open('geo_input.csv', newline='') as geo_csv:
reader = csv.reader(geo_csv)
next(reader, None) # skip the headers
for row in reader:
geo_points.append(CustomGeoPoint(row[0], row[1]))
# for every point, look at every point until one is found within 5 miles
for geo_point in geo_points:
for geo_point2 in geo_points:
dist = vincenty(geo_point.location, geo_point2.location).miles
if 0 < dist <= close_limit: # (0,close_limit]
geo_point.close_to_another_point = True
break
writer.writerow([geo_point.location.latitude, geo_point.location.longitude,
geo_point.close_to_another_point])
finally:
output.close()
正如您可能会看到的那样,这个解决方案非常慢。事实上太慢了,我让它运行了3 天,它仍然没有完成!
我考虑过尝试将数据分成块(多个 CSV 文件或其他内容),以便内部循环不必查看所有其他点,但随后我必须弄清楚如何确保边界每个部分都对照其相邻部分的边界进行检查,这似乎过于复杂,恐怕这比它的价值更令人头疼。
那么关于如何使这更快的任何指示?