데이터 액세스 모듈은 ArcGIS 버전 10.1에서 도입되었습니다. ESRI는 데이터 액세스 모듈을 다음과 같이 설명합니다 ( source ).
데이터 액세스 모듈 arcpy.da는 데이터 작업을위한 Python 모듈입니다. 편집 세션, 편집 작업, 향상된 커서 지원 (보다 빠른 성능 포함), 테이블 및 기능 클래스를 NumPy 배열로 변환하는 기능, 버전 관리, 복제본, 도메인 및 하위 유형 워크 플로를 지원합니다.
그러나 왜 커서 성능이 이전 세대의 커서보다 향상되었는지에 대한 정보는 거의 없습니다.
첨부 된 그림은 새 da
메소드 UpdateCursor와 이전 UpdateCursor 메소드 에 대한 벤치 마크 테스트 결과를 보여줍니다 . 기본적으로 스크립트는 다음 워크 플로우를 수행합니다.
- 랜덤 포인트 생성 (10, 100, 1000, 10000, 100000)
- 정규 분포에서 무작위로 표본을 추출하고 커서를 사용하여 무작위 점 속성 테이블의 새 열에 값을 추가합니다
- 신규 및 기존 UpdateCursor 메소드 모두에 대해 임의의 포인트 시나리오마다 5 회 반복 실행하고 평균값을 목록에 씁니다.
- 결과 플롯
da
그림과 같이 커서 성능을 향상시키기 위해 업데이트 커서를 사용하여 뒤에서 어떤 일이 일어나고 있습니까?
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()