Ich habe 2 Geodatenrahmen:
import geopandas as gpd
from shapely.geometry import Point
gpd1 = gpd.GeoDataFrame([['John',1,Point(1,1)],['Smith',1,Point(2,2)],['Soap',1,Point(0,2)]],columns=['Name','ID','geometry'])
gpd2 = gpd.GeoDataFrame([['Work',Point(0,1.1)],['Shops',Point(2.5,2)],['Home',Point(1,1.1)]],columns=['Place','geometry'])
und ich möchte den Namen des nächsten Punktes in gpd2 für jede Zeile in gpd1 finden:
desired_output =
Name ID geometry Nearest
0 John 1 POINT (1 1) Home
1 Smith 1 POINT (2 2) Shops
2 Soap 1 POINT (0 2) Work
Ich habe versucht, dies mit einer Lambda-Funktion zum Laufen zu bringen:
gpd1['Nearest'] = gpd1.apply(lambda row: min_dist(row.geometry,gpd2)['Place'] , axis=1)
mit
def min_dist(point, gpd2):
geoseries = some_function()
return geoseries
Antworten:
Sie können die Shapely-Funktion Nearest points direkt verwenden (die Geometrien der GeoSeries sind Shapely-Geometrien):
Erläuterung
quelle
sample_point = gpd2.geometry.unary_union[400] /
sample_point in gpd2.geometry
Dies gibt True zurück.gpd2.geometry == sample_point
Das kommt alles falsch raus.gpd2.geometry.geom_equals(sample_point)
funktioniert.Wenn Sie über große Datenrahmen
scipy
verfügen, hat die räumliche Indexmethode cKDTree.query
sehr schnelle Ergebnisse für die Suche nach nächsten Nachbarn geliefert . Da ein räumlicher Index verwendet wird, ist er um Größenordnungen schneller als das Durchlaufen des Datenrahmens und das Ermitteln des Minimums aller Entfernungen. Es ist auch schneller als die Verwendung vonnearest_points
Shapelys mit RTree (der über Geopandas verfügbaren räumlichen Indexmethode), da Sie mit cKDTree Ihre Suche vektorisieren können, während dies mit der anderen Methode nicht möglich ist.Hier ist eine Hilfsfunktion, die die Entfernung und den 'Namen' des nächsten Nachbarn in
gpd2
von jedem Punkt in zurückgibtgpd1
. Es wird davon ausgegangen, dass beide gdfs einegeometry
Spalte (von Punkten) haben.Und wenn Sie den nächstgelegenen Punkt zu einem LineString finden möchten, finden Sie hier ein voll funktionsfähiges Beispiel:
quelle
Herausgefunden:
Kritik ist natürlich willkommen. Ich bin kein Fan davon, gpd2 ['Dist'] für jede Zeile von gpd1 neu zu berechnen ...
quelle
Die Antwort von Gene hat bei mir nicht funktioniert. Schließlich entdeckte ich, dass gpd2.geometry.unary_union zu einer Geometrie führte, die nur ungefähr 30.000 meiner insgesamt ungefähr 150.000 Punkte enthielt. Für alle anderen, die auf dasselbe Problem stoßen, habe ich Folgendes gelöst:
quelle
Für alle, die Indexierungsfehler mit ihren eigenen Daten haben, während sie die ausgezeichnete Antwort von @ JHuw verwenden , bestand mein Problem darin, dass meine Indizes nicht ausgerichtet wurden. Das Zurücksetzen des Index von gdfA und gdfB hat meine Probleme gelöst. Vielleicht hilft Ihnen das auch bei Shakedk .
quelle