2017-07-31 72 views
6

Próbuję znaleźć wszystkich najbliższych sąsiadów, które są w promieniu 1 KM. Oto mój skrypt skonstruować drzewo i wyszukać najbliższe punktyOptymalizuj scipy najbliższego sąsiada wyszukiwania

from pysal.cg.kdtree import KDTree 

def construct_tree(s): 
    data_geopoints = [tuple(x) for x in s[['longitude','latitude']].to_records(index=False)] 
    tree = KDTree(data_geopoints, distance_metric='Arc', radius=pysal.cg.RADIUS_EARTH_KM) 
    return tree 

def get_neighbors(s,tree): 
    indices = tree.query_ball_point(s, 1) 
    return indices 

#Constructing the tree for search 
tree = construct_tree(data) 

#Finding the nearest neighbours within 1KM 
data['neighborhood'] = data['lat_long'].apply(lambda row: get_neighbors(row,tree)) 

Z tego co czytałem na stronie pysal, to mówi -

kd-drzewa zbudowany na szczycie funkcjonalności kd-drzewa w scipy . Jeśli używasz scipy 0.12 lub nowszego, używa scipy.spatial.cKDTree, w przeciwnym razie używa scipy.spatial.KDTree.

W moim przypadku powinno używać cKDTree. Działa to dobrze dla przykładowego zestawu danych, ale ponieważ tree.query_ball_point zwraca w rezultacie listę indeksów. Każda lista będzie zawierała 100 elementów. W przypadku moich punktów danych (2 miliony rekordów) liczba ta rośnie i po pewnym czasie zatrzymuje się z powodu problemu z pamięcią. Masz pomysł, jak rozwiązać ten problem?

+0

Czy rozważałeś zapisanie danych 'sąsiedztwa' nie w DataFrame? Na myśl przychodzi 'networkx.Graph'. –

+0

Niestety nie słyszałem o tym. Czy możesz napisać przykład? Mogę spróbować, być może. –

+0

https://networkx.github.io/ to biblioteka do pracy z danymi wykresu. W twoim przypadku będę przechowywać identyfikatory lokalizacji jako wierzchołki i dodawać krawędzie między lokalizacjami w odległości mniejszej niż 1 km od siebie. Dokumenty zawierają dobry samouczek. –

Odpowiedz

0

Na wszelki wypadek, jeśli ktoś szuka odpowiedzi na to pytanie, rozwiązałem go, znajdując najbliższych sąsiadów dla grupy (tree.query_ball_point może obsługiwać partie) i zapisując w bazie danych, a następnie przetwarzając następną grupę, zamiast wszystko w pamięci. Dzięki.

+0

Podajesz "tree.query_ball_point może obsługiwać partie". Czy możesz podać przykładowy kod? – ximiki

+1

W tym jednym, tree.query_ball_point (s, 1). s powinien być listą. –