ArcView 3.x Avenue Bitmaps (¿pestañas?) Vs. ArcView 10 Python Cursors


9

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!


1
¿Tienes ganas de publicar tu guión? No conozco ninguna avenida / python que use puntos de referencia GP.
Derek Swingley

Las uniones y consultas de tabla son mucho más rápidas en ArcView 3.2 (avenue) que cualquier ArcGIS 8.x a 10. * arcpy / python. básicamente debido a la cantidad (mucho más) de código en los productos ArcGIS.
Mapperz

2
@Mapperz Tienes toda la razón. Sin embargo, el procesamiento de fila por fila en ArcView 3.x es horriblemente lento debido a la sobrecarga interpretativa de 10,000X para cada solicitud (he comparado esto). Cuando uno puede evitar los bucles, utilizando solicitudes de "alto nivel" como uniones y consultas como usted sugiere, ArcView 3.x superará a ArcGIS, pero es plausible que en una prueba cara a cara que implique bucles explícitos sobre registros , cualquiera podría ganar por un margen relativamente leve.
whuber

@Whuber @Derek Thar que sea.
Nathanus

Respuestas:


2

No soy nuevo en programación pero soy muy nuevo en Python, así que tómalo con un poco de sal ...

copyRecord = arcpy.InsertCursor(outData)

¿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.


Buena atrapada. Lo intentaré cuando regrese a la oficina la próxima semana.
Nathanus

5

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:

  • gp.CopyFeatures ("Path to featureclass \ FeatureclassName", "'in_memory' \ FeatureclassName") - para clases de entidad y;
  • gp.CopyRow ("Ruta de acceso a featureclass \ FeatureTableName", "'in_memory' \ FeatureTableName"): para tablas en una tabla o clase de entidad 'in_memory'.

    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

  1. Shapefile (triste pero cierto)
  2. Geodatabase personal
  3. Geodatabase de archivos
  4. ArcSDE (incluso con conexión directa es más lento)

Pruebe estas sugerencias, ya que estoy tratando de compilar una lista de cosas que funcionan aquí en gis.stackexchange.com, vea aquí


La opción de memoria parece útil, pero el poder combinado de la tabla que estoy consultando contra los relojes es de casi 1 gb. Creo que tengo suficiente RAM para hacer esto posible, pero ¿el tamaño de la mesa corre el riesgo de un choque violento? Además, ¿qué es un contenedor de python?
Nathanus

Me sorprende que coloque gdb personal tan rápido como el archivo gdb, ya que eso se invirtió directamente desde mi experiencia. Sería interesante explorar eso en algún lugar / tiempo.
Matt Wilkie

Puede ser el proceso con el que estoy trabajando actualmente, pero he descubierto que un archivo gdb es más lento, pero solo. Yo diría que están a la par, y elegiría un archivo gdb sobre un gdb personal simplemente por las limitaciones del archivo. Estoy muy interesado en diseñar un punto de referencia para esto. ¿Estás interesado en ayudarme a definir algunas pruebas?
OptimizePrime

Traté de poner el archivo de forma en la memoria, y eso pareció hacer muy poco para ayudar ... de hecho, el script dejó de procesarse poco después.
Nathanus

3

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.


El único problema aquí es que estoy agregando datos no espaciales a datos espaciales. Es decir, estoy tomando el Shapecampo 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 los Shapescampos en movimiento (y su geometría)?
Nathanus el

No funcionaría con shapefiles ya Shapeque 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.
matt wilkie

1

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.


Gracias por la información. Algo que esperar, si nada más.
Nathanus
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.