12 votos

¿Por qué es tan dolorosamente lenta esta simple arpía script?

Tengo un simple arcpy script para actualizar un campo en un archivo de forma de punto con la información de la característica de polígono que está dentro. Lleva 9 minutos hacer 100 puntos en arcpy pero una unión espacial en arcmap es instantánea. Estoy seguro de que hay una forma rápida y establecida de resolver este problema. ¿Puede alguien indicarme la dirección correcta?

import took 0:00:07.085000
extent took 0:00:05.991000
one pt loop took 0:00:03.780000
one pt loop took 0:00:03.850000
one pt loop took 0:00:03.791000

import datetime
t1 = datetime.datetime.now()
import arcpy
t2 = datetime.datetime.now()
print "import took %s" %  ( t2-t1)
#set up environment
arcpy.env.workspace = "data\\"
arcpy.env.overwriteOutput = True

desc = arcpy.Describe("parcels.shp")
ext = desc.Extent
extent = (ext.XMin,ext.XMax,ext.YMin,ext.YMax)
t3 = datetime.datetime.now()
print "extent took %s" %  (t3 -t2)
fc = arcpy.CreateRandomPoints_management("", "malls.shp", "", ext, 100, "", "POINT", "")
arcpy.AddField_management("malls.shp", 'ParcelID', 'LONG')

rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in arcpy.SearchCursor('parcels.shp'):
        t6 = datetime.datetime.now()
        poly = polyrow.getValue('Shape')
        if extent[0]<pt.X<extent[1] and extent[2]<pt.Y<extent[3]:
            if poly.contains(pt):
                print "works"
                row.ParcelID = polyrow.Parcels_ID
                rows.updateRow(row)
                break #we can stop looking for matches since
        t7 = datetime.datetime.now()
        "a full poly loop took %s" % (t7-t6)
    t5 = datetime.datetime.now()
    print "one pt loop took %s" % (t5-t4)

print datetime.datetime.now() -t1

20voto

Aissen Puntos 131

Si necesitas crear un segundo cursor para parcels.shp hazlo fuera del bucle para tu primer cursor. Tal como está, tu script está creando un nuevo objeto cursor para cada fila en malls.shp que es lo que te está costando todo ese tiempo de procesamiento.

...
rows = arcpy.UpdateCursor('malls.shp',"","",'ParcelID')
polyrows = arcpy.SearchCursor('parcels.shp')
for row in rows:
    t4 = datetime.datetime.now()
    pt = row.Shape.getPart()
    for polyrow in polyrows:
...

10voto

auramo Puntos 161

El problema con la respuesta de @Jason (y su enfoque original) es que no aprovecha el índice espacial y requiere un bucle anidado de dos cursores que va a ser exponencialmente más lento a medida que aumente el número de puntos.

Un flujo de trabajo alternativo que puede ser más rápido y que al mismo tiempo le permite actualizar la clase de características puntuales en el lugar (la unión espacial sólo produce una nueva clase de características, no actualiza una ya existente) podría ser:

  1. Utilice La unión espacial para crear una clase de característica intermedia (quizás en memoria)
  2. Utilice Añadir Añadir Añadir para unirse a la clase de características intermedias a su clase de características puntuales existentes
  3. Utilice Calcular el campo o un UpdateCursor para copiar los valores en el campo unido al campo en la clase de característica de punto existente.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X