Nota: Si bien esta pregunta tiene una respuesta, cualquier otro consejo para optimizar un proceso de cursor sería muy apreciado. Estaré monitoreando cualquier actualización.
Actualmente, mi jefe (que trabaja en Avenue) y yo (trabajando en Python) intentamos resolver el mismo problema. Más bien, ambos lo hemos resuelto, pero la velocidad a la que operan nuestras soluciones son ... desarticuladas, por decir lo menos. Lo que su script procesa en 2 horas puede llevar el mío hasta 6. La única diferencia real en la sintaxis y la implementación en la lógica proviene de los mapas de bits de 3.x y los cursores de 10.x. Los dos:
1) Almacene valores de la Tabla 1.
2) Use esos valores para consultar una fila en la Tabla 2.
3) Almacene los valores de la Tabla 2 para insertarlos en la Tabla 3 como una nueva fila.
En ambos scripts, estos procesos se completan en dos bucles anidados. Antes de comenzar a profundizar en el maravilloso mundo de la optimización del código, ¿es este un evento esperado al comparar el rendimiento del script Avenue con Python? Esta no es la primera vez que sus guiones han superado en gran medida las mías en términos de tiempo de operación, por lo que me gustaría saber si hay algo de lo que deba estar al tanto antes de crucificarme por las horribles secuencias de comandos.
Aquí está mi script sin bits extraños:
import arcpy
import time
import sys
import os
def recordfindcopy(inFile,query,outFile):
findRecord = arcpy.SearchCursor(inFile,query)
for record in findRecord:
copyRecord = arcpy.InsertCursor(outData) # <--- D'oh! (See answer)
field = record.FIELD
copy = copyRecord.newRow()
copy.FIELD = field
copyRecord.insertRow(copy)
StreetsFileList = [r"Path",
r"Path"]
for sfile in StreetsFileList:
inStreets = sfile
inTable = r"Path"
outData = r"Path"
fsaEntry = arcpy.SearchCursor(inTable)
for row in fsaEntry:
id = row.ID
sQuery = "ID = %s " % (str(id))
recordfindcopy(inStreets,sQuery,outData)
EDITAR : Teniendo en cuenta algunos de los comentarios hasta ahora, me pregunto si podría haber una mejor manera de hacer esto a través de uniones, aunque dudo dado el tamaño brobdingnagian (¡palabra del día!) De las tablas. El corazón del procesamiento es agregar información de una tabla a cualquier registro coincidente en una segunda tabla y crear una tercera tabla que solo contenga los campos importantes. Quería probar esto usando SDE, pero parece que no es una opción disponible. Pensamientos? Pido disculpas si mis preguntas siempre están tan involucradas , pero estoy tratando de llegar al fondo de una molestia de larga data.
Respondido : la simple sugerencia de Jakub solo redujo el tiempo de procesamiento de 30 segundos por 500 registros a 3 segundos por 500 registros. Reiniciar el cursor de inserción en cada inserción ralentizó considerablemente las cosas (obviamente). Si bien esto puede no ser la mayor optimización que se puede hacer para este proceso cuando se compara con la velocidad de ArcView 3.x, es suficiente para mis propósitos en este momento. ¡Más sugerencias son bienvenidas!
fuente
Respuestas:
No soy nuevo en programación pero soy muy nuevo en Python, así que tómalo con un poco de sal ...
¿No debería establecerse el cursor de inserción antes del ciclo For Next? Me parece que si la ruta de acceso a los datos "out" se almacena en la variable "outData", entonces no es necesario restablecerla cada vez que itera. Creo que esto debería acelerar las cosas significativamente.
fuente
Asumiré que estás usando ArcPy, o arcgisscripting alrededor del 9.3. De cualquier manera, las técnicas aquí acelerarán su procesamiento ... tal vez mejor que sus jefes.
Lo primero es realizar búsquedas e inserciones con cualquier medio que no sea memoria va a ralentizar sus procesos. Avenue está optimizado para funcionar rápidamente y utiliza una base de código C \ C ++ (corrígeme si me equivoco) que es inherentemente más rápido en IO que la mayoría de los otros lenguajes. Python también es rápido (igual de rápido), excepto donde hay gastos generales al enganchar en bibliotecas c para realizar operaciones, como ArcPy o arcgisscripting.
Intente esto primero:
1. Copie las tablas que necesita usar en la memoria usando los métodos:
Esto le permitirá utilizar la memoria como un disco RAM y le ahorrará una gran cantidad de golpes en el disco. También puede crear una clase de entidad o tabla en la memoria sustituyendo el parámetro FeatureDataset con 'in_memory'.
Use los contenedores de python tanto como sea posible. Esto también aumentará la velocidad.
Finalmente, el orden de eficiencia en la lectura y escritura de información para formatos ESRI es
Pruebe estas sugerencias, ya que estoy tratando de compilar una lista de cosas que funcionan aquí en gis.stackexchange.com, vea aquí
fuente
Apuesto a que no es que Avenue sea más rápido que Python, sino que ArcView3 es más rápido que ArcGIS (en lo que estás tratando de hacer).
Dado que, por lo que parece, este es esencialmente un ejercicio no espacial, es posible que desee experimentar accediendo a las tablas de la base de datos directamente (por ejemplo, no use arcpy) con algo como dbfpy u odbc (no he probado ninguno de los dos). Personalmente, he encontrado que la línea de comandos ogr2ogr de la suite gdal / ogr son órdenes de magnitud más rápidas que las transacciones equivalentes en arcgis. Sin embargo, solo me he sumergido ligeramente en las habilidades de consulta de OGR, y no he construido nada usando solo los enlaces de Python, así que no sé si esa velocidad se transfiere.
fuente
Shape
campo junto con algunos otros y creando un nuevo registro que contendrá la geometría y los datos no espaciales adicionales. ¿Dpfpy y odbc explicarán losShapes
campos en movimiento (y su geometría)?Shape
que no está almacenado en el .dbf. Teóricamente podría funcionar con una geodatabase personal (.mdb) usando odbc, pero desconfío de ese enfoque, especialmente porque ya hay una ruta comprobada con OGR, que ya conoce tanto el archivo shape como el gdb personal.Esta no es una respuesta especialmente útil en este momento, pero espere a ArcGIS 10.1. En la cumbre de esri dev de este año, se nos dijo que el soporte del cursor arcpy 10.1 se ha reescrito por completo y es significativamente más rápido. Durante el plenario hubo un reclamo de mejoras de velocidad de alrededor de 8x.
fuente