Uwaga: Chociaż na to pytanie można znaleźć odpowiedź, wszelkie dalsze wskazówki dotyczące optymalizacji procesu kursora byłyby bardzo mile widziane. Będę monitorować wszelkie aktualizacje.
Obecnie zarówno mój szef (który pracuje w Avenue), jak i ja (pracujący w Pythonie) próbujemy rozwiązać ten sam problem. Obaj raczej to rozwiązaliśmy, ale szybkość, z jaką działają nasze rozwiązania, jest ... co najmniej rozłączna. To, co jego skrypt wykonuje w ciągu 2 godzin, może zająć moje nawet 6. Jedyna prawdziwa różnica w składni i implementacji logiki wynika z map bitowych 3.x i kursorów 10.x. My oboje:
1) Zapisz wartości z tabeli 1.
2) Użyj tych wartości, aby wykonać zapytanie do wiersza w tabeli 2.
3) Zapisz wartości z tabeli 2 i wstaw do tabeli 3 jako nowy wiersz.
W obu skryptach procesy te są wykonywane w dwóch zagnieżdżonych pętlach. Czy zanim zacznę zagłębiać się w cudowny świat optymalizacji kodu, jest to oczekiwane zjawisko podczas porównywania wydajności skryptu Avenue z Pythonem? To nie pierwszy raz, gdy jego skrypty znacznie przewyższają moje pod względem czasu działania, dlatego chciałbym wiedzieć, czy jest coś, o czym powinienem wiedzieć, zanim ukrzyżuję się za okropne skrypty.
Oto mój skrypt bez zbędnych bitów:
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)
EDYCJA : Biorąc pod uwagę niektóre dotychczasowe komentarze, zastanawiam się, czy może być lepszy sposób, aby to zrobić za pomocą złączeń, chociaż jestem wątpliwy, biorąc pod uwagę brobdingnagian (słowo dnia!) Rozmiar tabel. Sercem przetwarzania jest dołączenie informacji z jednej tabeli do dowolnych pasujących rekordów w drugiej tabeli i utworzenie trzeciej tabeli zawierającej tylko ważne pola. Chciałem wypróbować to za pomocą SDE, ale wydaje się, że nie jest to dostępna opcja. Myśli? Przepraszam, jeśli moje pytania są zawsze tak zaangażowane , ale staram się dotrzeć do sedna długotrwałej irytacji.
Odpowiedzi : sama prosta sugestia Jakuba skróciła czas przetwarzania z 30 sekund na 500 rekordów do 3 sekund na 500 rekordów. Ponowne zainicjowanie kursora wstawiania na każdej wkładce znacznie spowolniło (oczywiście). Chociaż może nie być to najlepsza optymalizacja, jaką można zrobić dla tego procesu, gdy porównamy go z szybkością ArcView 3.x, w tym momencie wystarczy dla moich celów. Dalsze sugestie są bardzo mile widziane!
źródło
Odpowiedzi:
Nie jestem nowy w programowaniu, ale bardzo nowy w Pythonie, więc weź to z odrobiną soli ...
Czy kursor wstawiania nie powinien być ustawiony przed pętlą For Next? Wydaje mi się, że jeśli ścieżka do danych „out” jest przechowywana w zmiennej „outData”, to nie trzeba jej resetować za każdym razem, gdy iterujesz. Sądzę, że powinno to znacznie przyspieszyć.
źródło
Zakładam, że używasz ArcPy lub arcgisscripting około 9.3. Tak czy inaczej, techniki tutaj przyspieszą przetwarzanie ... może lepiej niż twoi szefowie.
Pierwszą rzeczą jest wykonanie wyszukiwania, a wstawienie na dowolnym nośniku innym niż pamięć spowolni twoje procesy. Avenue jest zoptymalizowany do szybkiej pracy i wykorzystuje bazę kodu C \ C ++ (popraw mnie, jeśli się mylę), która jest z natury szybsza w IO niż w większości innych języków. Python jest również szybki (tak samo szybki), z wyjątkiem przypadków, gdy nałożenie się do bibliotek c jest narzutem w celu wykonania operacji, takich jak ArcPy lub arcgisscripting.
Spróbuj najpierw:
1. Skopiuj tabele, których potrzebujesz, do pamięci, używając metod -
Pozwoli to na użycie pamięci, takiej jak dysk RAM, i pozwoli zaoszczędzić wiele miejsca na dysku. Możesz także utworzyć klasę obiektów lub tabelę w pamięci, zastępując parametr FeatureDataset parametrem „in_memory”.
Używaj kontenerów python tak często, jak to możliwe. Zwiększy to również prędkość.
Wreszcie, kolejność zapewniania efektywności odczytu i zapisu informacji dla formatów ESRI jest następująca
Wypróbuj te sugestie, ponieważ próbuję skompilować listę rzeczy, które działają tutaj na gis.stackexchange.com zobacz tutaj
źródło
Założę się, że nie jest tak, że Avenue jest szybszy niż Python, ale że ArcView3 jest szybszy niż ArcGIS (w tym, co próbujesz zrobić).
Ponieważ z jego brzmienia jest to ćwiczenie zasadniczo nieprzestrzenne, możesz poeksperymentować z bezpośrednim dostępem do tabel bazy danych (np. Nie używaj arcpy) za pomocą czegoś takiego jak dbfpy lub odbc (sam nie próbowałem żadnego z nich). Osobiście znalazłem poleceń ogr2ogr z gdal / OGR suite być rzędy wielkości szybciej niż równoważnych transakcji w ArcGIS. Jednak tylko nieco zanurzyłem się w możliwości zapytań OGR i nie zbudowałem niczego, używając tylko powiązań pytona, więc nie wiem, czy ta prędkość się utrzyma.
źródło
Shape
pole wraz z kilkoma innymi i tworzę nowy rekord, który będzie zawierał geometrię i dodatkowe dane nieprzestrzenne. Czy dpfpy i odbc uwzględniają ruchomeShapes
pola (i ich geometrię)?Shape
nie są przechowywane w .dbf. Teoretycznie może współpracować z osobistą geobazą (.mdb) przy użyciu odbc, ale jestem ostrożny z tego podejścia, zwłaszcza, że istnieje już sprawdzona droga z OGR, która już zna zarówno plik kształtu, jak i osobisty gdb.W tej chwili nie jest to szczególnie przydatna odpowiedź, ale poczekaj na ArcGIS 10.1. Na tegorocznym szczycie esri dev powiedziano nam, że obsługa kursorów arcpy 10.1 została całkowicie przepisana i jest znacznie szybsza. Podczas sesji plenarnej pojawiła się prośba o poprawę prędkości około 8x.
źródło