Các cách để tăng tốc tập lệnh Python chạy dưới dạng công cụ ArcGIS [đã đóng]


31

Đây là một câu hỏi khá chung chung. Tôi chỉ tự hỏi những mẹo và thủ thuật mà các lập trình viên GIS đã sử dụng để tăng tốc các tập lệnh phức tạp mà bạn nhập vào hộp công cụ và chạy.

Tôi làm việc hầu hết hàng ngày bằng cách viết các tập lệnh nhỏ để giúp những người dùng không phải là GIS tại văn phòng của tôi xử lý dữ liệu GIS. Tôi đã thấy rằng việc xử lý ArcGIS 10.0 nói chung chậm hơn 9.3.1 và đôi khi nó còn chậm hơn khi chạy tập lệnh python.

Tôi sẽ liệt kê một ví dụ cụ thể về một kịch bản mất hơn 24 giờ để chạy. Đó là một vòng lặp lập bảng diện tích của raster trong bộ đệm cho mỗi hình dạng trong bộ đệm. Bộ đệm có khoảng 7000 hình dạng. Tôi không tin rằng nó sẽ chạy lâu như vậy. Một

while x <= layerRecords:

    arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
    arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
    TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

    arcpy.AddMessage ("          - Row: " + str(x) + " completed")
    x = x + 1
    z = z + 1

Trước khi bất cứ ai nói điều đó, tôi đã chạy khu vực lập bảng trên toàn bộ bộ đệm, nhưng nó tạo ra lỗi nếu chạy trên nhiều hơn 1 bản ghi. Đó là một công cụ thiếu sót, nhưng tôi phải sử dụng nó.

Dù sao, nếu bất cứ ai có bất kỳ ý tưởng nào về cách tối ưu hóa, hoặc tăng tốc kịch bản này, nó sẽ được đánh giá cao nhất. Nếu không, bạn có bất kỳ thủ thuật tăng tốc nào cho python, khi được sử dụng trong ArcGIS không?

Câu trả lời:


26

Một vài gợi ý tiềm năng để giúp tăng tốc quá trình của bạn là:

  1. Chọn Layer By Attribution có thể nằm trong tập lệnh chỉ dành cho Python mà không cần khởi chạy ArcGIS Desktop. Bạn cần chuyển đổi tham chiếu "buff" của mình từ tham chiếu dựa trên tệp sang tham chiếu "lớp ArcGIS", ArcGIS có thể xử lý các truy vấn lựa chọn. Sử dụng arcpy.MakeFeatureLayer_man Quản lý ("buff", "buff_lyr") phía trên vòng lặp "while" của bạn, sau đó thay đổi các tham chiếu của bạn bên dưới vòng lặp while để sử dụng "buff_lyr".

  2. Xử lý càng nhiều thao tác GP của bạn bằng cách sử dụng không gian làm việc in_memory càng tốt ... Sử dụng arcpy.CopyFeatures_man quản lý (shapefile, "in_memory \ memFeatureClass") để chuyển nguồn của bạn vào bộ nhớ. Điều này chỉ hoạt động tốt nếu bạn có đủ RAM để đọc tất cả (các) lớp tính năng mà bạn cần vào bộ nhớ. Tuy nhiên, hãy coi chừng rằng có một số hoạt động GP không thể chạy bằng không gian làm việc in_memory (Ví dụ: công cụ Project).

Từ bài viết trợ giúp trực tuyến ArcGIS 9.3 " Dữ liệu trung gian và không gian làm việc đầu " (lưu ý, ngôn ngữ này đã bị xóa khỏi trợ giúp 10.0 & 10.1):

LƯU Ý: Chỉ các bảng và các lớp đối tượng (điểm, đường, đa giác) có thể được ghi vào không gian làm việc in_memory. Không gian làm việc in_memory không hỗ trợ các thành phần cơ sở dữ liệu địa lý mở rộng như các kiểu con, tên miền, biểu diễn, cấu trúc liên kết, mạng hình học và bộ dữ liệu mạng. Chỉ các tính năng đơn giản và bảng có thể được viết.

Từ bài viết trợ giúp trực tuyến ArcGIS 10.1 " Sử dụng không gian làm việc trong bộ nhớ ":

Các cân nhắc sau đây phải được thực hiện khi quyết định ghi đầu ra vào không gian làm việc trong bộ nhớ:

  • Dữ liệu được ghi vào không gian làm việc trong bộ nhớ là tạm thời và sẽ bị xóa khi đóng ứng dụng.
  • Bảng, lớp tính năng và trình quét có thể được ghi vào không gian làm việc trong bộ nhớ.
  • Không gian làm việc trong bộ nhớ không hỗ trợ các yếu tố cơ sở dữ liệu địa lý mở rộng như các kiểu con, miền, biểu diễn, cấu trúc liên kết, mạng hình học và bộ dữ liệu mạng.
  • Bộ dữ liệu tính năng hoặc thư mục không thể được tạo trong không gian làm việc trong bộ nhớ.

1
Điều đó thật tuyệt! Tôi đã tìm kiếm một cách để sử dụng các lựa chọn bên ngoài ArcMap nhưng cho đến nay vẫn không thành công. Về vấn đề này, nó thực sự đã đẩy thời gian mỗi hàng của tôi xuống còn khoảng 13 giây từ 20 giây. Nhưng, tôi đã thực hiện một công việc nhanh chóng khác và thực hiện MakeFeatureLayer trong vòng lặp và nó đã giảm xuống còn 9 giây. Tôi đã làm điều này bằng cách tạo một tính năng từ mỗi hình dạng hơn là lập bảng từ lớp tính năng. Tôi vẫn muốn đưa nó xuống hơn nữa nếu có thể, nhưng đó là một quá trình nhanh hơn nhiều!
Cody Brown

Như đã đề cập trong # 2, hãy sử dụng CopyFeatures để tạo một bản sao dữ liệu nguồn của bạn in_memory, sau đó tạo Feature_layer của bạn dựa vào nguồn in_memory. Mặc dù bản sao ban đầu vào bộ nhớ có thể thêm vài giây trước, bạn có thể thấy rằng việc xử lý copyfeatures + tabulation_areas để có tổng thời gian xử lý nhanh hơn mô hình hiện tại của bạn.
RyanDalton

Tôi cũng đã thử điều đó và có vẻ như giải pháp đó sẽ làm cho quá trình lặp nhanh hơn nhưng không được. Tạo lớp tính năng trong vòng lặp cho kết quả trong khoảng 8-10 giây mỗi vòng, trong khi tạo lớp tính năng trước khi vòng lặp kết quả trong 11 - 14 giây mỗi vòng. Tôi không chắc tại sao vì giải pháp của bạn có vẻ như sẽ xử lý nhanh hơn. Tôi có 8GB RAM, vì vậy tôi nghi ngờ đó sẽ là vấn đề.
Cody Brown

Đồng thời đối phó các tính năng với in_memory trước vòng lặp và sau đó vẫn tạo lớp tính năng trong vòng lặp dẫn đến hiệu suất nhanh hơn một chút. Nó khá nhiều ở lại 8 giây mỗi hàng cho mỗi vòng lặp. Sẽ giảm tổng thời gian xử lý từ 26 giờ xuống 22.
Cody Brown

Sau khi thêm ý tưởng của bạn, kịch bản của tôi được cải thiện đáng kể. Cảm ơn rất nhiều cho sự giúp đỡ của bạn và mọi người!
Cody Brown

28

Các kỹ thuật tối ưu hóa python nói chung có thể giúp bạn tiết kiệm đáng kể thời gian.

Một kỹ thuật thực sự tốt để giảm thiểu tình trạng nắm giữ trong tập lệnh của bạn là sử dụng mô-đun cProfile tích hợp:

from cProfile import run
run("code") # replace code with your code or function

Kiểm tra bằng cách sử dụng một mẫu dữ liệu nhỏ sẽ cho phép bạn xác định chính xác các cuộc gọi chức năng nào đang chiếm nhiều thời gian nhất.

Con trỏ chung cho mã python nhanh hơn:

  • Việc hiểu danh sách thường nhanh hơn vòng lặp
  • Máy phát điện sản xuất một mặt hàng cùng một lúc thay vì tạo toàn bộ danh sách cùng một lúc
  • Sử dụng xrange thay vì phạm vi trong python 2 (không cần thiết trong 3)
  • Bộ có thể ra khỏi danh sách phôi khi nói đến việc xác định nếu một mục có mặt trong tập nhưng nói chung là chậm hơn so với danh sách khi nói đến iterating trên nội dung của họ Nguồn
  • Các cuộc gọi chức năng thể tốn kém để thực hiện Nguồn
  • Thêm mẹo và chi tiết kiểm tra tại đây Mẹo về Perfomance Python và tại đây 10 Mẹo và vấn đề tối ưu hóa Python

Liên quan đến tập lệnh của bạn, tôi không thể nhận xét về các khía cạnh ArcPy vì tôi không cài đặt Arc trên máy tính này nhưng bạn có thể muốn thử sử dụng vòng lặp for thay vì vòng lặp while xem điều đó có cải thiện gì không. Ngoài ra x = x + 1 có thể được viết là x + = 1:

for record in layerRecords:
arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

arcpy.AddMessage ("          - Row: " + str(x) + " completed")
x+=1
y+=1

1
Tôi đã sử dụng hai liên kết bạn để lại trên viên đạn cuối cùng của bạn và có thể thực sự giúp kịch bản của tôi với một vài sửa chữa nhanh chóng!
Cody Brown

Nếu tôi có thể trao hai câu trả lời đúng, tôi sẽ làm. Trong khi câu trả lời của bạn thực sự đưa ra rất nhiều ý tưởng về cách tăng tốc con trăn, @RyanDalton đưa ra ý tưởng có tác động mạnh nhất. Cảm ơn rất nhiều!
Cody Brown

13

Hãy chắc chắn rằng bạn đang ghi vào ổ đĩa trên máy tính. Tiếp cận trên mạng khi không cần thiết thực sự có thể làm chậm quá trình xử lý. Thậm chí có thể nhanh hơn để sao chép dữ liệu là bước đầu tiên trong quy trình để giữ cho việc đọc-ghi tiếp theo nhanh nhất có thể

Chạy tập lệnh hoàn toàn bên ngoài ArcMap có thể nhanh hơn nhiều. Nếu Bản đồ không bắt buộc trong quá trình xử lý, thì đừng sử dụng ArcMap.


Tôi đã thấy rằng việc chạy một tập lệnh bên trong một mô hình từ ArcCatalog (tự nó bên trong một Calculate Valuehộp thoại) sẽ xử lý nhanh hơn so với việc chạy cùng một tập lệnh từ cửa sổ ArcPy trong ArcMap. Đó hoàn toàn là một quan sát giai thoại.
Cindy Jayakumar

1
Tôi tin rằng tôi cần một bản đồ để Tabulation hoạt động bình thường, nhưng tôi sẽ thử nó. Nếu nó hoạt động bên ngoài ArcMap, tôi cá là nó sẽ tăng tốc. Ngoài ra, tôi đang chạy đĩa cục bộ, tốc độ của tập lệnh đã tăng gấp đôi.
Cody Brown

Đáng buồn là Chọn không hoạt động bên ngoài ArcMap và điều đó là cần thiết bởi vì tôi cần phải thực hiện hình dạng bảng theo hình dạng.
Cody Brown

3
@ CodyBrown- Bạn không chính xác về Chọn không hoạt động bên ngoài phiên ArcMap. Xem phản hồi của tôi về việc sử dụng công cụ MakeFeatureLayer.
RyanDalton

Ryan nói đúng. Khi công cụ chọn được sử dụng riêng, nó sẽ tạo chế độ xem bảng về dữ liệu không gian hoặc dữ liệu bảng của bạn. Khi sử dụng nó trong ModelBuilde hoặc trong tập lệnh, bạn phải tạo chế độ xem và trong trường hợp của bạn, hãy tạo nó bằng cách sử dụng công cụ MakeFeatureLayer.
dchaboya

6

Điều này có thể không trả lời câu hỏi của bạn để chạy các công cụ ArcPy bên trong ArcMap nhưng khi tôi cần thực hiện một số xử lý nhuần nhuyễn với các công cụ xử lý địa lý và Python, tôi có xu hướng chạy nó bên ngoài hệ thống GIS bằng IDE PyScripter . Tôi đã tìm thấy nó chạy nhanh hơn. Tôi cũng đã sử dụng RAMDISK cho các bộ dữ liệu đầu ra tạm thời nhỏ (hơi giống với không gian làm việc in_memory )

Vâng, họ là những lời khuyên hàng đầu của tôi! :)


2
Để làm vấy bẩn câu trả lời này phần nào, khi chạy các tập lệnh từ Python IDE, nhiều người sử dụng chức năng theo dõi để hỗ trợ xem các biến và hỗ trợ gỡ lỗi khác nhau. Hàm này có thể làm chậm các tập lệnh một cách ồ ạt nếu nó làm quá nhiều vì nó được gọi là TẤT CẢ THỜI GIAN và đôi khi điều này được cài đặt hoàn toàn mà không cần sự can thiệp của người dùng. Có một trường hợp bệnh lý cụ thể mà tôi đã quan sát thấy một tập lệnh Python chạy trong ArcMap chạy trong 4 phút, trong khi tập lệnh tương tự từ Wing IDE mất 3 giờ. Ngay khi được chạy từ Python.exe mà không có Cánh, nó đã quay trở lại lãnh thổ thời gian chạy ~ 2-3 phút.
Jason Scheirer

1
Tôi đã đau đầu để điều chỉnh các tập lệnh của mình trên ArMap, đôi khi tôi không thể hoàn toàn, cho đến khi tôi chuyển sang Pyscripter, nó có thể cắt giảm thời gian thực hiện so với Arcmap, mà không cần sử dụng bất kỳ mẹo tối ưu hóa nào.
geogeek

@JasonScheirer bạn đã tìm thấy tinh chỉnh trong Cánh để tắt cái này chưa? Tôi chắc chắn có một.
Giá của Curtis

5

Hãy thử nhận xét arcpy.SetProTHERorLabel và xem bạn tăng tốc bao nhiêu. Tôi đã thấy rằng bất kỳ đầu ra màn hình nào, quay trở lại với sự kinh ngạc của DOS, làm chậm đáng kể thời gian xử lý. Nếu bạn thực sự cần xem đầu ra đó, hãy thử hiển thị nó ở mỗi vòng lặp thứ N.


4

Đảm bảo rằng bạn xóa bất kỳ import xxxxdòng nào không được sử dụng.

(ví dụ: nếu bạn chưa sử dụng bất kỳ hàm toán học nào bạn có import Math, việc này sẽ mất một chút thời gian từ khi tải tập lệnh)

Mặc dù điều này sẽ không có tác động lớn đến các tập lệnh đơn chạy (chẳng hạn như tập lệnh của bạn), nhưng nó sẽ ảnh hưởng đến bất kỳ tập lệnh nào chạy thường xuyên và lặp đi lặp lại.


7
Tôi nghi ngờ bất kỳ mô-đun Python tiêu chuẩn nào cũng mất hơn một phần nghìn thời gian để mô-đun Arcpy khởi tạo.
blah238

1
@ blah238 import Mathcó lẽ là một ví dụ tồi. Tuy nhiên, một số thư viện ArcPy lớn hơn, mất một lượng thời gian đáng kể để tải lên.
nagytech

1
điều này vẫn tắt chỉ trong vài giây (nhiều nhất là!), chứ không phải vài giờ
Mike T

1
@MikeToews Đối với các tập lệnh chạy thường xuyên và lặp đi lặp lại, một vài giây sẽ xuất hiện trong vài ngày / tuần, v.v. Mặc dù điều này không giải quyết được vấn đề chính của OP, anh ấy đã hỏi các mẹo chung.
nagytech
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.