Come migliorare le prestazioni quando si usano i cursori ArcGIS in Python con tavoli grandi?


10

Ho una classe caratteristica piuttosto grande in un file geodatabase (~ 4 000 000 record). Questa è una griglia di punti regolare con una risoluzione di 100 m.

Ho bisogno di eseguire una sorta di generalizzazione su questo livello. Per questo, creo una nuova griglia in cui ogni punto si trova nel mezzo di 4 punti "vecchi":

 *     *     *     *
    o     o     o
 *     *     *     *
    o     o     o
 *     *     *     *

[*] = punto della griglia originale - [o] = punto della nuova griglia

Il valore dell'attributo di ogni nuovo punto viene calcolato in base ai valori ponderati dei suoi 4 vicini nella vecchia griglia. In questo modo eseguo il ciclo su tutti i punti della mia nuova griglia e, per ciascuno di essi, eseguo il ciclo su tutti i punti della mia vecchia griglia, al fine di trovare i vicini (confrontando i valori di X e Y nella tabella degli attributi). Una volta trovati 4 vicini, usciamo dal circuito.

Non c'è complessità metodologica qui, ma il mio problema è che, sulla base dei miei primi test, questo script durerà per settimane per completare ...

Vedi qualche possibilità per renderlo più efficiente? Alcune idee in cima alla mia testa:

  • Indicizza i campi X e Y => L'ho fatto ma non ho notato cambiamenti significativi nelle prestazioni
  • Esegui una query spaziale per trovare i vicini anziché uno basato sugli attributi. Sarebbe davvero d'aiuto? Quale funzione spaziale in ArcGIS dovrebbe svolgere il lavoro? Dubito che, ad esempio, il buffering di ogni nuovo punto si dimostrerà più efficiente
  • Trasforma la classe di caratteristiche in un array NumPy. Sarebbe d'aiuto? Finora non ho lavorato molto con NumPy e non mi piacerebbe immergermi a meno che qualcuno non mi dica che potrebbe davvero aiutare a ridurre i tempi di elaborazione
  • Qualunque altra cosa?

Quale versione di Arcmap stai usando?
Martin,

Hai considerato PostGIS? È un'opzione?
Chad Cooper,

Mi dispiace di aver dimenticato che: ArcGIS 10.1 // Python 2.7
Stéphane Henriod

No, PostGIS non è purtroppo un'opzione, purtroppo le mie mani sono abbastanza legate qui ... Nel migliore dei casi posso usare Oracle con le funzioni SDE
Stéphane Henriod,

Risposte:


13

Che cosa succede se si immettono i punti in un array intorpidito e si utilizza un cKDTree scipy per cercare i vicini. Elaborando nuvole di punti LiDAR con un gran numero di punti (> 20 milioni) in diversi MINUTI usando questa tecnica. C'è documentazione qui per kdtree e qui per la conversione numpy. Fondamentalmente, leggi la x, y in una matrice e iteri su ogni punto della matrice trovando indici di punti entro una certa distanza (vicinanza) di ogni punto. È possibile utilizzare questi indici per calcolare altri attributi.


questa risposta è migliore della mia
radouxju,

Mi piace questa idea ma non ho Scipy sulla workstation su cui sto lavorando (e senza diritti di amministratore). Se riesco a installare questo pacchetto, allora lo proverò
Stéphane Henriod,

4

Sono con Barbarossa ... i cursori arcpy sono follemente pazzi, quindi li uso solo per attraversare un tavolo o una classe caratteristica esattamente una volta. Se non riesco a completare il lavoro in un ciclo, utilizzo il cursore per riempire un altro tipo di struttura di dati e lavorare con quello.

Se non vuoi seccarti con numpy, crea un semplice dizionario Python in cui usi le tue coordinate come una semplice chiave di testo e inserisci gli attributi necessari per il calcolo in un elenco come valore dell'elemento del dizionario.

In un secondo momento puoi facilmente ottenere i valori necessari per calcolare un punto semplicemente acquisendoli dal tuo dizionario (che è incredibilmente veloce, a causa dei dizionari hashindex degli articoli).


In realtà mi piace la tua idea con i dizionari e l'ho appena implementata. Funziona davvero molto meglio ... fino a quando non scrivo effettivamente i risultati con row.insertRow () ... Qualche idea su come posso migliorare anche questa parte?
Stéphane Henriod,

Ho avuto un problema simile in cui ho dovuto selezionare circa 10.000 punti su 14 milioni. e poi cancellalo. arcpy.cursors dove solo in grado di eliminare circa 1 o 2 punti al secondo (!). così ho installato il modulo pyodbc per eliminarli con una singola istruzione DELETE SQL in un solo secondo. AGGIORNARE su SQL ti porterà molti miglioramenti, purché tu voglia solo modificare gli attributi ... tuttavia dovrai installare ulteriori moduli Python ... ma ne vale la pena.
Jürgen Zornig,

2

Per una griglia regolare, dovrebbe essere di gran lunga più efficiente lavorare in un formato raster. Converti la tua prima griglia in un raster, puoi ricampionare alla stessa risoluzione usando un interpolatore bilineare ma spostando l'immagine di output di 1/2 pixel in X e Y e di nuovo ai punti se hai ancora bisogno di punti.

EDIT: per regole di decisione complesse, puoi convertire ciascuno dei campi di cui hai bisogno come nuova banda raster, quindi fai quattro copie di quelle bande e ti sposta raster nelle 4 direzioni di 1/2 pixel (+50, - 50), (+ 50, + 50), (-50, -50) e (-50, + 50). Quindi puoi usare la normale algebra delle mappe


Grazie, ho davvero pensato a questa soluzione ma non sono sicuro se / come posso implementare il calcolo del nuovo valore se in formato raster. Mi spiego: per ogni nuovo punto (o nuova cella raster) ho bisogno di calcolare il suo valore in quanto tale: prendo il valore di ciascuno dei suoi vicini. Ognuno di questi valori ha una probabilità di dare un valore particolare al nuovo punto. Ad esempio, se un vicino ha il valore 202, allora darà il valore 3 (con un peso di 1) o il valore 11 (con un peso di 5). Riassumiamo quindi per tutti e 4 i vicini e troviamo il nuovo valore ... Non sono sicuro che sia molto chiaro ...
Stéphane Henriod,

PS: il calcolo per trovare il nuovo valore può, in alcuni casi, basarsi su 2 attributi, non solo uno, che potrebbe scartare l'approccio Raster
Stéphane Henriod

per la tua somma ponderata, hai solo bisogno di due raster: uno in cui ricampi il prodotto dei pesi e i valori, il secondo in cui ricampi solo i pesi. Se si divide il primo per il secondo, si ottiene la somma ponderata.
Radouxju,

1
@ StéphaneHenriod - come suggerimento, potresti prendere in considerazione la modifica della domanda per aggiungere queste specifiche aggiuntive. Data la domanda iniziale, penso che questa risposta abbia molto senso, ma con queste nuove informazioni, la risposta di Barbarossa sembra buona.
nicksan,

2

Grazie a tutti per il vostro aiuto!

Alla fine ho trovato un modo molto non pitonico per risolvere questo problema ... Quello che in realtà stava impiegando più tempo a calcolare era trovare i 4 vicini di ogni punto. Piuttosto che usare gli attributi X e Y (o con un cursore arcpy o all'interno di un'altra struttura di dati, come un dizionario Python), ho finito per usare lo strumento ArcGIS Genera vicino al tavolo . Presumo che questo sfrutti gli indici spaziali e le prestazioni sono ovviamente molto più elevate, senza che io debba implementare l'indice da solo.


0

Il problema con i cursori è che puoi scorrere in un solo modo e non puoi tornare indietro. Sebbene non sia raccomandato, puoi popolare le bellezze in una struttura se hai intenzione di rivisitarle.

Se sei stato in grado di elaborare le tue funzionalità in un singolo ciclo, ti suggerisco di abilitare il riciclaggio. È un parametro della tua funzione di ricerca featureclass che consente a Python di riutilizzare la memoria allocata da vecchie funzionalità e di rendere molto più veloce l'attraversamento delle funzioni in un cursore. Puoi elaborare la tua griglia dell'80% più velocemente.

Il problema è che non è possibile abilitare il riciclaggio se si prevede di memorizzare le funzioni recuperate da un cursore.


Voglio esplorare questo argomento del "cursore di riciclo" ma non riesco a trovare alcuna documentazione nella Guida di ESRI. Avete un link? Il cursore di ricerca non ha un parametro di riciclo. Select_by_Attribute non ha questo parametro. Non vedo nulla in ENV.
Klewis,


1
Non credo che "riutilizzare i cursori" sia disponibile tramite ArcPy, solo con i core Arcobjects.
Klewis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.