Làm cách nào để cải thiện hiệu suất khi sử dụng con trỏ ArcGIS trong Python với các bảng lớn?


10

Tôi có một lớp tính năng điểm khá lớn trong cơ sở dữ liệu địa lý tệp (~ 4 000 000 bản ghi). Đây là một lưới điểm thông thường với độ phân giải 100m.

Tôi cần phải thực hiện một loại khái quát trên lớp này. Đối với điều này, tôi tạo một lưới mới trong đó mỗi điểm nằm ở giữa 4 điểm "cũ":

 *     *     *     *
    o     o     o
 *     *     *     *
    o     o     o
 *     *     *     *

[*] = điểm của lưới ban đầu - [o] = điểm của lưới mới

Giá trị thuộc tính của mỗi điểm mới được tính dựa trên các giá trị trọng số của 4 lân cận của nó trong lưới cũ. Do đó, tôi lặp trên tất cả các điểm của lưới mới của mình và đối với mỗi điểm trong số chúng, tôi lặp trên tất cả các điểm của lưới cũ của mình để tìm hàng xóm (bằng cách so sánh các giá trị của X và Y trong bảng thuộc tính). Khi 4 hàng xóm đã được tìm thấy, chúng tôi ra khỏi vòng lặp.

Không có sự phức tạp về phương pháp ở đây nhưng vấn đề của tôi là, dựa trên các thử nghiệm đầu tiên của tôi, kịch bản này sẽ kéo dài trong nhiều tuần để hoàn thành ...

Bạn có thấy bất kỳ khả năng để làm cho nó hiệu quả hơn? Một vài ý tưởng trên đỉnh đầu của tôi:

  • Lập chỉ mục các trường X và Y => Tôi đã làm điều đó nhưng không nhận thấy bất kỳ thay đổi hiệu suất đáng kể nào
  • Thực hiện một truy vấn không gian để tìm hàng xóm thay vì truy vấn dựa trên thuộc tính. Điều đó thực sự sẽ giúp? Chức năng không gian nào trong ArcGIS nên thực hiện công việc? Tôi nghi ngờ rằng, ví dụ, đệm từng điểm mới sẽ chứng minh hiệu quả hơn
  • Chuyển đổi lớp tính năng thành một NumPy Array. Điều đó sẽ giúp? Tôi đã không làm việc nhiều với NumPy cho đến nay và tôi không muốn đi sâu vào nó trừ khi có ai đó nói với tôi rằng nó thực sự có thể giúp giảm thời gian xử lý
  • Còn gì nữa không?

Phiên bản Arcmap nào bạn đang sử dụng?
Martin

Bạn đã xem PostGIS chưa? Đó có phải là một lựa chọn không?
Chad Cooper

Xin lỗi vì tôi đã quên rằng: ArcGIS 10.1 // Python 2.7
Stéphane Henriod

Không, PostGIS không may không phải là một lựa chọn, tay tôi không may bị trói chặt ở đây ... Tốt nhất tôi có thể sử dụng Oracle với các chức năng SDE
Stéphane Henriod

Câu trả lời:


13

Điều gì sẽ xảy ra nếu bạn cho các điểm vào một mảng numpy và sử dụng một cKDTree xảo quyệt để tìm kiếm hàng xóm. Tôi xử lý các đám mây điểm LiDAR với số lượng điểm lớn (> 20 triệu) trong vài PHÚT bằng kỹ thuật này. Có tài liệu ở đây cho kdtree và ở đây để chuyển đổi numpy. Về cơ bản, bạn đọc x, y thành một mảng và lặp lại qua từng điểm trong mảng tìm chỉ số của các điểm trong một khoảng cách nhất định (vùng lân cận) của mỗi điểm. Bạn có thể sử dụng các chỉ số này để tính toán các thuộc tính khác.


câu trả lời này tốt hơn của tôi
radouxju

Tôi thích ý tưởng này nhưng tôi không có ý kiến ​​gì về máy trạm mà tôi đang làm việc (và không có quyền quản trị). Nếu tôi quản lý để cài đặt gói này, thì tôi sẽ dùng thử
Stéphane Henriod

4

Tôi với Barbarossa ... các con trỏ cực kỳ khập khiễng, vì vậy tôi chỉ sử dụng chúng để đi qua một bảng hoặc lớp đặc trưng chính xác một lần. Nếu tôi không thể hoàn thành công việc trong một chu kỳ, tôi sử dụng con trỏ để điền vào một số loại cấu trúc dữ liệu khác và làm việc với điều đó.

Nếu bạn không muốn gặp rắc rối với numpy, chỉ cần tạo một từ điển python đơn giản trong đó bạn sử dụng tọa độ của mình làm khóa văn bản đơn giản và điền các thuộc tính bạn cần để tính vào danh sách làm giá trị của mục từ điển.

Trong bước thứ hai, bạn có thể dễ dàng nhận được các giá trị bạn cần để tính điểm bằng cách đơn giản lấy chúng từ từ điển của bạn (điều này cực kỳ nhanh, vì từ điển hashindex của các mục).


Tôi thực sự thích ý tưởng của bạn với từ điển và tôi chỉ thực hiện nó. Nó thực sự hoạt động tốt hơn nhiều ... cho đến khi tôi thực sự viết kết quả với một hàng.insertRow () ... Bạn có biết cách nào để cải thiện phần này không?
Stéphane Henriod

Tôi đã có một vấn đề tương tự khi tôi phải chọn khoảng 10.000 điểm trong số 14 Mio. và sau đó xóa nó. arcpy.cursors nơi chỉ có thể xóa khoảng 1 hoặc 2 điểm mỗi giây (!). vì vậy tôi đã cài đặt mô-đun pyodbc để xóa chúng bằng một câu lệnh XÓA SQL duy nhất chỉ trong một giây. CẬP NHẬT qua SQL sẽ mang lại cho bạn nhiều cải tiến, miễn là bạn chỉ muốn sửa đổi các thuộc tính ... tuy nhiên bạn sẽ phải cài đặt thêm các mô-đun python ... nhưng nó đáng giá.
Jürgen Zornig

2

Đối với một lưới thông thường, sẽ hiệu quả hơn nhiều khi làm việc ở định dạng raster. Chuyển đổi lưới đầu tiên của bạn thành raster, bạn có thể lấy mẫu lại ở cùng độ phân giải bằng cách sử dụng bộ nội suy song tuyến tính nhưng thay đổi hình ảnh đầu ra của bạn bằng 1/2 pixel trong X và Y, và quay lại điểm nếu bạn vẫn cần có điểm.

EDIT: đối với các quy tắc quyết định phức tạp, bạn có thể chuyển đổi từng trường mà bạn cần dưới dạng băng raster mới, sau đó bạn tạo bốn bản sao của các dải đó và bạn dịch chuyển raster theo 4 hướng bằng 1/2 pixel (+50, - 50), (+ 50, + 50), (-50, -50) và (-50, + 50). Sau đó, bạn có thể sử dụng đại số bản đồ thông thường


Cảm ơn tôi đã thực sự nghĩ đến giải pháp này nhưng tôi không chắc chắn nếu / làm thế nào tôi có thể thực hiện tính toán giá trị mới nếu ở định dạng raster. Hãy để tôi giải thích: đối với mỗi điểm mới (hoặc ô raster mới) tôi cần tính giá trị của nó như sau: Tôi lấy giá trị của từng điểm lân cận. Mỗi giá trị đó có xác suất đưa ra một giá trị cụ thể cho điểm mới. Ví dụ: nếu một hàng xóm có giá trị 202, thì nó sẽ cho giá trị 3 (với trọng số 1) hoặc giá trị 11 (với trọng số là 5). Sau đó chúng tôi tổng hợp cho cả 4 người hàng xóm và tìm giá trị mới ... Không chắc điều này có rõ ràng không ...
Stéphane Henriod

PS: tính toán để tìm giá trị mới, trong một số trường hợp, có thể dựa trên 2 thuộc tính, không chỉ một thuộc tính, có thể loại bỏ cách tiếp cận Raster
Stéphane Henriod

đối với tổng trọng số của bạn, bạn chỉ cần hai raster: một trong đó bạn lấy mẫu lại sản phẩm của các trọng số và các giá trị, thứ hai trong đó bạn chỉ lấy lại các trọng số. Nếu bạn chia số thứ nhất cho số thứ hai, bạn sẽ có được tổng số có trọng số của mình.
radouxju

1
@ StéphaneHenriod - như một gợi ý, bạn có thể xem xét chỉnh sửa câu hỏi để thêm các thông số kỹ thuật bổ sung này. Với câu hỏi ban đầu, tôi nghĩ câu trả lời này có ý nghĩa, nhưng với thông tin mới này, câu trả lời của Barbarossa có vẻ tốt.
nicksan

2

Cảm ơn mọi người đã giúp đỡ!

Cuối cùng tôi đã tìm thấy một cách rất phi kim để giải quyết vấn đề này ... Điều thực sự tốn nhiều thời gian tính toán nhất là tìm ra 4 người hàng xóm của mỗi điểm. Thay vì sử dụng các thuộc tính X và Y (với con trỏ hình cung hoặc trong cấu trúc dữ liệu khác, chẳng hạn như một bộ sưu tập python), tôi đã kết thúc bằng cách sử dụng công cụ ArcGIS Tạo gần bảng . Tôi cho rằng điều này tận dụng các chỉ số không gian và hiệu suất rõ ràng cao hơn nhiều, mà tôi không phải tự mình thực hiện chỉ số.


0

Vấn đề với con trỏ là bạn chỉ có thể quay vòng qua chúng theo một cách và bạn không thể quay lại. Mặc dù không được khuyến nghị, bạn có thể đưa các feautres vào một cấu trúc nếu bạn dự định xem lại chúng.

Nếu bạn có thể xử lý các tính năng của mình trong một vòng lặp, tôi khuyên bạn nên cho phép tái chế. Đó là một tham số trên chức năng featureclass tìm kiếm của bạn cho phép python sử dụng lại bộ nhớ được phân bổ bởi các tính năng cũ và giúp truyền tải các tính năng trong một con trỏ nhanh hơn nhiều. Bạn có thể xử lý lưới của bạn nhanh hơn 80%.

Vấn đề là bạn không thể cho phép tái chế nếu bạn dự định lưu trữ các tính năng đã truy xuất từ ​​một con trỏ.


Tôi muốn khám phá chủ đề "con trỏ tái chế" này nhưng không thể tìm thấy bất kỳ tài liệu nào về Trợ giúp ESRI. Bạn có một liên kết? Con trỏ tìm kiếm không có tham số tái chế. Chọn_by_Attribution không có tham số như vậy. Tôi không thấy gì trong ENV.
klewis

Tôi đã viết một bài báo một thời gian trước husseinnasser.com/2009/08/when-to-use-recycling-coder.html?m=1
hnasr

1
Tôi không nghĩ rằng "tái sử dụng con trỏ" có sẵn thông qua ArcPy, chỉ với Arcobjects cốt lõi.
klewis
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.