Le module d'accès aux données a été introduit avec ArcGIS version 10.1. ESRI décrit le module d'accès aux données comme suit ( source ):
Le module d'accès aux données, arcpy.da, est un module Python pour travailler avec des données. Il permet de contrôler la session d'édition, les opérations d'édition, une prise en charge améliorée du curseur (y compris des performances plus rapides), des fonctions de conversion des tables et des classes d'entités vers et depuis les tableaux NumPy, et la prise en charge des flux de travail de gestion des versions, des répliques, des domaines et des sous-types.
Cependant, il existe très peu d'informations sur la raison pour laquelle les performances du curseur sont améliorées par rapport à la génération précédente de curseurs.
La figure ci-jointe montre les résultats d'un test de référence sur la nouvelle da
méthode UpdateCursor par rapport à l'ancienne méthode UpdateCursor. Essentiellement, le script effectue le workflow suivant:
- Créer des points aléatoires (10, 100, 1000, 10000, 100000)
- Échantillonner au hasard à partir d'une distribution normale et ajouter de la valeur à une nouvelle colonne dans la table attributaire de points aléatoires avec un curseur
- Exécutez 5 itérations de chaque scénario ponctuel aléatoire pour les nouvelles et anciennes méthodes UpdateCursor et écrivez la valeur moyenne dans les listes
- Tracer les résultats
Que se passe-t-il en arrière-plan avec le da
curseur de mise à jour pour améliorer les performances du curseur au degré indiqué sur la figure?
import arcpy, os, numpy, time
arcpy.env.overwriteOutput = True
outws = r'C:\temp'
fc = os.path.join(outws, 'randomPoints.shp')
iterations = [10, 100, 1000, 10000, 100000]
old = []
new = []
meanOld = []
meanNew = []
for x in iterations:
arcpy.CreateRandomPoints_management(outws, 'randomPoints', '', '', x)
arcpy.AddField_management(fc, 'randFloat', 'FLOAT')
for y in range(5):
# Old method ArcGIS 10.0 and earlier
start = time.clock()
rows = arcpy.UpdateCursor(fc)
for row in rows:
# generate random float from normal distribution
s = float(numpy.random.normal(100, 10, 1))
row.randFloat = s
rows.updateRow(row)
del row, rows
end = time.clock()
total = end - start
old.append(total)
del start, end, total
# New method 10.1 and later
start = time.clock()
with arcpy.da.UpdateCursor(fc, ['randFloat']) as cursor:
for row in cursor:
# generate random float from normal distribution
s = float(numpy.random.normal(100, 10, 1))
row[0] = s
cursor.updateRow(row)
end = time.clock()
total = end - start
new.append(total)
del start, end, total
meanOld.append(round(numpy.mean(old),4))
meanNew.append(round(numpy.mean(new),4))
#######################
# plot the results
import matplotlib.pyplot as plt
plt.plot(iterations, meanNew, label = 'New (da)')
plt.plot(iterations, meanOld, label = 'Old')
plt.title('arcpy.da.UpdateCursor -vs- arcpy.UpdateCursor')
plt.xlabel('Random Points')
plt.ylabel('Time (minutes)')
plt.legend(loc = 2)
plt.show()