Мне нужно сопоставить несколько сотен тысяч узлов их ближайшим соседям в виде набора из нескольких десятков тысяч других узлов. Естественно, я бы использовал пространственный индекс, чтобы ускорить этот процесс. Ранее я смог это сделать очень быстро, сгенерировав тесселяцию Вороного для меньшего набора узлов и используя пространственные запросы MySQL, чтобы определить, какие узлы в первом наборе попали в область, связанную с узлом второго набора. Это удалось запустить всего за несколько минут. С тех пор я перешел из среды MySQL и хотел сделать весь процесс в python. Я повернулся к популярному пространственному индексу STRtree, предоставленному стройным пакетом. Однако я обнаружил, что этот индекс невероятно медленный. Я пытался использовать как ближайший геометрический запрос с наборами узлов, так и запрос пересечения геометрии с областями Вороного, и получал только 51.787 совпадающих узлов в секунду, что занимало около 4,5 часов для запуска каждого набора узлов, которые я обрабатываю. Почему стройный такой медленный? Или я использую его неправильно?
Некоторые фрагменты кода:
class Network:
...
def load_network(self, planspath):
log.info('Fetching temperatures.')
temperatures = self.fetch_temperatures()
log.info('Fetching centroids.')
centroids = self.fetch_centroids()
log.info('Fetching links.')
links = self.fetch_links()
Centroid.steps = len(next(iter(temperatures.values())))
log.info('Building spatial index (strtree) from centroids.')
points = []
for centroid in centroids.values():
uuid = centroid[0]
self.centroids[uuid] = Centroid(temperatures[centroid[1]])
point = loads(centroid[2])
setattr(point, 'id', uuid)
points.append(point)
tree = STRtree(points)
log.info('Mapping links to centroids.')
for link in links:
node = loads(link[4])
point = tree.nearest(node)
self.links[link[0]] = Link(link[1], link[2], self.centroids[point.id])
log.info('Loading network routes from output plans file.')
self.routes = self.fetch_routes(planspath)