Ist es bei einer großen Stichprobe (~ 1 Million) ungleichmäßig verteilter Punkte möglich, ein unregelmäßiges Raster (in der Größe, aber möglicherweise auch unregelmäßig in der Form?) Zu generieren, das eine festgelegte Mindestanzahl von n Punkten enthält?
Es ist für mich weniger wichtig, wenn generierte "Zellen" eines solchen Gitters genau n Punkte oder mindestens n Punkte enthalten.
Ich kenne Lösungen wie genvecgrid in ArcGIS oder Create Grid Layer in QGIS / mmgis. Sie alle erstellen jedoch reguläre Gitter, die zu einer Ausgabe mit leeren Zellen (kleineres Problem - ich könnte sie einfach verwerfen) oder Zellen mit Punkteanzahl führen kleiner als n (größeres Problem, da ich eine Lösung zum Zusammenfassen dieser Zellen benötigen würde, wahrscheinlich mit einigen Tools von hier ?).
Ich habe vergeblich gegoogelt und bin offen für kommerzielle (ArcGIS & Extensions) oder kostenlose (Python, PostGIS, R) Lösungen.
quelle
Antworten:
Ich sehe, dass MerseyViking einen Quadtree empfohlen hat . Ich wollte dasselbe vorschlagen und um es zu erklären, hier ist der Code und ein Beispiel. Der Code ist in geschrieben
R
, sollte sich aber leicht beispielsweise nach Python portieren lassen.Die Idee ist bemerkenswert einfach: Teilen Sie die Punkte ungefähr in der Hälfte in der x-Richtung, dann teilen Sie die beiden Hälften rekursiv entlang der y-Richtung, wobei sich die Richtungen auf jeder Ebene abwechseln, bis keine Aufteilung mehr erwünscht ist.
Da die Absicht darin besteht, tatsächliche Punktpositionen zu verschleiern, ist es nützlich, den Teilungen eine gewisse Zufälligkeit zu verleihen . Ein schneller und einfacher Weg, dies zu tun, besteht darin, an einem Quantil einen kleinen Zufallsbetrag abzuspalten, der von 50% abweicht. Auf diese Weise ist es sehr unwahrscheinlich, dass (a) die Aufteilungswerte mit den Datenkoordinaten übereinstimmen, so dass die Punkte eindeutig in durch die Partitionierung erzeugte Quadranten fallen und (b) Punktkoordinaten nicht präzise aus dem Quadtree rekonstruiert werden können.
Da die Absicht besteht, eine Mindestanzahl
k
von Knoten in jedem Quadtree-Blatt beizubehalten , implementieren wir eine eingeschränkte Form von Quadtree. Es werden (1) Clustering-Punkte in Gruppen mit jeweils zwischenk
und 2 *k
-1 Elementen und (2) Mapping der Quadranten unterstützt.Dieser
R
Code erstellt einen Baum von Knoten und Terminalblättern, die nach Klassen unterschieden werden. Die Klassenkennzeichnung beschleunigt die Nachbearbeitung, z. B. das unten gezeigte Plotten. Der Code verwendet numerische Werte für die IDs. Dies funktioniert bis zu einer Tiefe von 52 im Baum (unter Verwendung von Doubles; wenn vorzeichenlose lange Ganzzahlen verwendet werden, beträgt die maximale Tiefe 32). Für tiefere Bäume (die in jeder Anwendung höchst unwahrscheinlich sind, da mindestensk
* 2 ^ 52 Punkte beteiligt wären) müssten IDs Zeichenfolgen sein.Es ist zu beachten, dass das rekursive Divide-and-Conquer-Design dieses Algorithmus (und folglich der meisten Nachverarbeitungsalgorithmen) bedeutet, dass der Zeitbedarf O (m) und die RAM-Auslastung O (n)
m
ist, wobei die Anzahl von ist Zellen undn
ist die Anzahl der Punkte.m
ist proportional zun
dividiert durch die minimalen Punkte pro Zelle,k
. Dies ist nützlich, um die Berechnungszeiten abzuschätzen. Wenn zum Beispiel 13 Sekunden benötigt werden, um n = 10 ^ 6 Punkte in Zellen mit 50-99 Punkten (k = 50) zu unterteilen, ist m = 10 ^ 6/50 = 20000. Wenn Sie stattdessen bis 5-9 unterteilen möchten Punkte pro Zelle (k = 5), m ist 10-mal größer, so dass das Timing auf ca. 130 Sekunden ansteigt. (Da der Vorgang des Aufteilens eines Satzes von Koordinaten um ihre Mitten schneller wird, wenn die Zellen kleiner werden, betrug das tatsächliche Timing nur 90 Sekunden.) Bis zu k = 1 Punkt pro Zelle dauert es ungefähr sechsmal länger Noch, oder neun Minuten, und wir können davon ausgehen, dass der Code tatsächlich etwas schneller ist.Bevor wir fortfahren, generieren wir einige interessante Daten mit unregelmäßigen Abständen und erstellen ihren eingeschränkten Quadtree (0,29 Sekunden verstrichene Zeit):
Hier ist der Code, um diese Diagramme zu erstellen. Der
R
Polymorphismuspoints.quadtree
wird ausgenutzt : Wird aufgerufen, wenn diepoints
Funktion beispielsweise auf einquadtree
Objekt angewendet wird . Die Stärke davon zeigt sich in der extrem einfachen Funktion, die Punkte gemäß ihrer Clusterkennung einzufärben:Das Zeichnen des Rasters selbst ist etwas komplizierter, da die für die Quadtree-Partitionierung verwendeten Schwellenwerte wiederholt abgeschnitten werden müssen. Derselbe rekursive Ansatz ist jedoch einfach und elegant. Verwenden Sie bei Bedarf eine Variante, um polygonale Darstellungen der Quadranten zu erstellen.
Als weiteres Beispiel habe ich 1.000.000 Punkte generiert und diese in Gruppen von jeweils 5-9 aufgeteilt. Das Timing betrug 91,7 Sekunden.
Als Beispiel für die Interaktion mit einem GIS schreiben wir alle Quadtree-Zellen mithilfe der
shapefiles
Bibliothek als Polygon-Shapefile aus . Der Code emuliert die Clipping-Routinen vonlines.quadtree
, muss jedoch dieses Mal Vektorbeschreibungen der Zellen generieren. Diese werden als Datenrahmen zur Verwendung mit dershapefiles
Bibliothek ausgegeben .Die Punkte selbst können direkt mithilfe
read.shp
oder durch Importieren einer Datendatei mit (x, y) Koordinaten gelesen werden .Anwendungsbeispiel:
(Verwenden Sie eine beliebige Ausdehnung, um
xylim
hier ein Fenster in eine Teilregion zu öffnen oder die Zuordnung auf eine größere Region zu erweitern. Der Standardwert für diesen Code ist die Ausdehnung der Punkte.)Dies allein reicht aus: Eine räumliche Verknüpfung dieser Polygone mit den ursprünglichen Punkten identifiziert die Cluster. Einmal identifiziert, erzeugen Datenbank "Zusammenfassungs" -Operationen eine Zusammenfassungsstatistik der Punkte in jeder Zelle.
quelle
shapefiles
Paket lesen oder Sie können (x, y) Koordinaten in ASCII-Text exportieren und mit lesenread.table
. (2) Ich empfehle,qt
in zwei Formen zu schreiben : erstens als Punkt-Shapefile,xy
in dem dieid
Felder als Cluster-IDs enthalten sind; Zweitens, wenn die durchgezeichneten Liniensegmentelines.quadtree
als Polylinien-Shapefile ausgeschrieben werden (oder wenn bei analoger Verarbeitung die Zellen als Polygon-Shapefile geschrieben werden). Dies ist so einfach wie das Ändernlines.quadtree.leaf
der Ausgabexylim
als Rechteck. (Siehe die Änderungen.)quad
: (1) initialisierenid=1
; (2) Änderungid/2
zuid*2
derlower=
Leitung; (3) Nehmen Sie eine ähnliche Änderung wieid*2+1
in derupper=
Zeile vor. (Ich werde meine Antwort entsprechend anpassen.) Dies sollte auch die Flächenberechnung berücksichtigen: Abhängig von Ihrem GIS sind alle Flächen positiv oder alle negativ. Wenn sie alle negativ sind, kehren Sie die Listen fürx
undy
in umcell.quadtree.leaf
.Überprüfen Sie, ob dieser Algorithmus genügend Anonymität für Ihre Datenprobe bietet:
Wenn zum Beispiel der Mindestschwellenwert 3 ist:
quelle
Wie wäre es, ähnlich wie bei Paulos interessanter Lösung, mit einem Quad-Tree-Unterteilungsalgorithmus?
Stellen Sie die Tiefe ein, in die der Quadtree gehen soll. Sie können auch eine minimale oder maximale Anzahl von Punkten pro Zelle festlegen, sodass einige Knoten tiefer / kleiner als andere sind.
Unterteilen Sie Ihre Welt, indem Sie leere Knoten verwerfen. Spülen und wiederholen, bis die Kriterien erfüllt sind.
quelle
Ein anderer Ansatz besteht darin, ein sehr feines Gitter zu erstellen und den max-p-Algorithmus zu verwenden. http://pysal.readthedocs.org/en/v1.7/library/region/maxp.html
quelle