Wie man dataframe Zeilen, in denen X-und Y-Koordinaten außerhalb des Polygons
Ich versuche zu Adresse das folgende Problem. Nehmen wir einen dataframe (geladen aus einer txt-Datei) mit der folgenden Struktur (und Tausende von Zeilen):
foo.head()
X Y Z 0 125417.5112 536361.8752 -1750.0 1 127517.7647 533925.8644 -1750.0 2 128144.1000 533199.4000 -1750.0 3 128578.8385 532904.9288 -1750.0 4 125417.5112 536361.8752 -1750.0 ....
Die Daten darstellt, X -, Y-und Z-Koordinaten.
Ich auch eine Menge Punkte, die definieren, die ein geschlossenes polygon. Diese sind in ein numpy-array:
polypoints
array([[ 125417.5112, 536361.8752],
[ 127517.7647, 533925.8644],
[ 128144.1 , 533199.4 ],
....
[ 125417.5112, 536361.8752]])
Wie kann ich meine filter dataframe so löschen Sie die Zeilen, die NICHT fallen in dem geschlossenen polygon?
Ich habe versucht die Definition des Polygons mit shapely.geometry
polygon
. By doing:
poly = Polygon(polypoints)
Diese funktioniert einwandfrei. Aber ich bin an einem Verlust, wie Sie weiter mit diesem.
Hilfe ist sehr willkommen
– – – – – EDIT – – – – –
Bitte siehe unten für die aktualisierte Lösung
- Der klassische Algorithmus für diese zu zeichnen ist eine Linie vom Punkt zur Unendlichkeit, der keine Schnittmenge mit irgendeinem der Punkte und zählen, wie viele Kanten kreuzt. Seltsam für drinnen, noch für draußen.
- Haben Sie einen Blick auf Geopandas: geopandas.org/set_operations.html
- das wäre für eine „einfache“ geometrische Form, denke ich. In meinem Fall ist es ein Komplexes polygon, damit es nicht so geradlinig. Auch ich bin auf der Suche nach einer Lösung, die arbeitet die ganze Zeit
- die overlay-Funktion sieht wirklich vielversprechend aus. In Sie suchen im moment. Brauchen, um herauszufinden, ob es angewendet werden kann, auch mit polygon-und Punkte
- Es funktioniert mit jedem Komplexität polygon, es wird einfach teurer zu berechnen als die Anzahl der Kanten geht.
Die original Lösung von @MrT funktioniert Super. Dennoch, mit Blick auf geopandas wie vorgeschlagen von @Rutger Kassies, ich habe auch eine andere Lösung gefunden. Zuerst braucht man zum installieren der geopandas Paket. Dann wird der folgende code funktioniert bei mir:
Hoffe, das hilft, wenn jemand vor einer ähnlichen problem. Auch, weitere Infos über die räumliche Verknüpfung kann gefunden werden auf der website geopandas. Beachten Sie, dass diese Funktionalität nicht benötigen eine operation zwischen Polygonen, funktioniert aber auch mit Punkte und Polygone
–EDIT —
Scheint es, dass die geo-pandas-Funktion ist viel schneller. Aber um fair zu sein die nicht-geo pandas Lösung hat auch zum konvertieren der X-und Y formschöne zeigen Sie Elemente und führen Sie dann die Kreuzung Bewertung
timeit
– Modul für Daten-set von mittlerer Größe eine Vorstellung zu bekommen, welcher Weg Sie sparen Zeit, wenn Sie haben eine Menge Daten zu STEMMEN. +1Ich bin nicht so vertraut mit
shapely
. Vielleicht haben Sie eine echte pandas zu unterstützen. Afaik unterstützen Sie vektorisiert numpy-Funktionen, so wäre ich nicht überrascht.Ein Weg, um herauszufinden, den die Punkte innerhalb eines gegebenen Polygons, wäre die Verwendung von pandas
apply()
Funktion:Ausgang für mein Spielzeug Datensatz
In formschönen,
contains
wirklich bedeutet, dass innerhalb des Polygons, das schließt die Grenze. Wenn Sie möchten, dass auch die Grenze, die Sie verwenden solltenintersects
Nun die Antwort auf Ihre Frage ist einfach. Legen Sie einfach die Zeilen, die
False
in diese neue Spalte:Leider haben Sie immer noch eine Schleife über die polygon-Liste. Es wäre interessant, wenn jemand wüsste einen Weg, wie um zu testen, alle Punkte und alle Polygone, die ohne eine (explizite) Schleife. Ich habe gesehen, eine MultiPolygon-Konstruktor der Klasse auf Ihrer website, also vielleicht eine Kombination aller Polygone in einer Klasse würde den trick tun. Aber testen Sie im Vorfeld, dass dies eine gültige Auswahl. Ein MultiPolygon ist ungültig, wenn seine Mitglieder berühren sich mit einer unendlichen Anzahl von Punkten entlang einer Linie.
Edit: Scheinbar ist in Python 2.7 funktioniert das nicht. Sehen akozi Antwort für einen 2.7 kompatibel zu beantworten.
Python 2.7
müssen Siecontains_points
stattcontains
. Es scheint auch Probleme mit einzelnen Elementen. Habe ich ein funktionsfähiges Beispiel bearbeitet diese Antwort in eine Antwort auf meine eigenen.Ich hatte Mühe, imitiert die genau die Lösung, Mr. T vorgeschlagen, in
Python 2.7
. So, hier ist der kleine Unterschied, den ich machen musste, um es arbeiten inPython 2.7
.Scheint es, dass die alte version von contains_points hatte Probleme bei der Ausführung mit einem einzigen Punkt. So habe ich es bis zu Lesen Sie alle Punkte und hängen Sie diese Liste in einer neuen Spalte.