큰 테이블이있는 Python에서 ArcGIS 커서를 사용할 때 성능을 향상시키는 방법은 무엇입니까?


10

파일 지오 데이터베이스 (~ 4000000 레코드)에 꽤 큰 포인트 피쳐 클래스가 있습니다. 이것은 100m 해상도의 일반적인 점 그리드입니다.

이 계층에서 일종의 일반화를 수행해야합니다. 이를 위해 각 포인트가 4 개의 "오래된"포인트의 중간에있는 새 그리드를 만듭니다.

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

[*] = 원래 그리드의 점-[o] = 새 그리드의 점

각 새 점의 속성 값은 이전 그리드에있는 4 개의 이웃에 대한 가중치를 기반으로 계산됩니다. 따라서 새 그리드의 모든 점을 반복하고 각각에 대해 이웃을 찾기 위해 이전 표의 모든 점을 반복합니다 (속성 테이블에서 X 및 Y 값을 비교하여). 4 명의 이웃이 발견되면 루프에서 빠져 나옵니다.

여기에는 방법 론적 복잡성이 없지만 내 문제는 첫 번째 테스트를 기반 으로이 스크립트가 몇 주 동안 지속된다는 것입니다 ...

보다 효율적으로 만들 가능성이 있습니까? 내 머리 위에 몇 가지 아이디어가 있습니다.

  • X와 Y => 필드를 인덱싱하십시오. 그렇지만 중요한 성능 변화는 눈치 채지 못했습니다.
  • 속성 기반 쿼리가 아닌 인접 쿼리를 찾으려면 공간 쿼리를 수행하십시오. 실제로 도움이 되겠습니까? ArcGIS에서 어떤 공간 기능을 수행해야합니까? 예를 들어, 각각의 새로운 지점을 버퍼링하는 것이 더 효율적일 것이라고 의심합니다
  • 기능 클래스를 NumPy 배열로 변환하십시오. 도움이 되겠습니까? 나는 지금까지 NumPy와 많은 일을하지 않았으며 누군가가 실제로 처리 시간을 줄이는 데 도움이 될 것이라고 말하지 않는 한 그것에 뛰어 들기를 원하지 않습니다.
  • 다른 거있어?

어떤 버전의 Arcmap을 사용하고 있습니까?
Martin

PostGIS를 고려 했습니까? 그게 옵션인가요?
채드 쿠퍼

죄송합니다 : ArcGIS 10.1 // Python 2.7
Stéphane Henriod

아니, PostGIS는 안타깝게도 옵션이 아니며, 내 손은 불행히도 여기에 매우 묶여 있습니다 ... 기껏해야 SDE 기능으로 Oracle을 사용할 수 있습니다
Stéphane Henriod

답변:


13

점을 numpy 배열에 공급하고 scipy cKDTree를 사용하여 이웃을 찾으면 어떻게됩니까? 이 기술을 사용하여 몇 분 내에 많은 수의 포인트 (> 2 천만)가있는 LiDAR 포인트 클라우드를 처리합니다. 문서가 여기 kdtree과 여기 NumPy와 변환을 위해. 기본적으로 x, y를 배열로 읽고 배열의 각 점을 반복하여 각 점의 특정 거리 (이웃) 내에있는 점의 인덱스를 찾습니다. 이 색인을 사용하여 다른 속성을 계산할 수 있습니다.


이 답변은 내 것보다 낫습니다
radouxju

이 아이디어가 마음에 들지만 작업중인 워크 스테이션에 관리자 권한이 없습니다. 이 패키지를 설치
했다면

4

나는 Barbarossa와 함께 있습니다 ... arcpy 커서는 미친 듯이 절름발이이므로 테이블이나 피쳐 클래스를 정확히 한 번만 통과하는 데만 사용합니다. 한 사이클에서 작업을 수행 할 수 없으면 커서를 사용하여 다른 종류의 데이터 구조를 채우고 그 작업을 수행합니다.

numpy로 번거롭지 않으려면 좌표를 간단한 텍스트 키로 사용 하는 간단한 파이썬 사전 을 만들고 사전 항목의 값으로 계산에 필요한 속성을 목록에 채우십시오 .

두 번째 단계에서는 사전에서 값을 가져 와서 점을 계산하는 데 필요한 값을 쉽게 얻을 수 있습니다 (사전의 해시 색인으로 인해 엄청나게 빠릅니다).


나는 실제로 당신의 아이디어를 사전으로 좋아하고 그것을 방금 구현했습니다. 실제로 실제로 row.insertRow ()로 결과를 작성할 때까지 훨씬 더 잘 작동합니다.
Stéphane Henriod

나는 14 Mio 중 약 10.000 점을 선택 해야하는 비슷한 문제가있었습니다. 그런 다음 삭제하십시오. 초당 약 1 또는 2 포인트 (!) 만 삭제할 수있는 arcpy.cursors. 그래서 pyodbc 모듈을 설치하여 단 1 초 만에 단일 SQL DELETE 문으로 삭제했습니다. SQL을 통한 업데이트는 속성을 수정하려는 경우에만 추가 개선을 가져옵니다. 그럼에도 불구하고 추가 파이썬 모듈을 설치해야하지만 그만한 가치가 있습니다.
Jürgen Zornig

2

일반 그리드의 경우 래스터 형식으로 작업하는 것이 훨씬 더 효율적이어야합니다. 첫 번째 그리드를 래스터로 변환하면 이중 선형 보간기를 사용하여 동일한 해상도에서 다시 샘플링 할 수 있지만 출력 이미지를 X 및 Y에서 1/2 픽셀만큼 이동 한 다음 여전히 포인트가 필요한 경우 포인트로 다시 되돌릴 수 있습니다.

편집 : 복잡한 의사 결정 규칙의 경우 새 래스터 밴드로 필요한 각 필드를 변환 한 다음 해당 밴드의 사본을 4 개 만들고 래스터를 4 방향으로 1/2 픽셀 (+ 50,- 50), (+ 50, + 50), (-50, -50) 및 (-50, + 50). 그런 다음 일반 대수를 사용할 수 있습니다


고마워 나는 실제로이 솔루션에 대해 생각했지만 래스터 형식의 경우 새 값의 계산을 구현할 수 있는지 / 어떻게하는지 잘 모르겠습니다. 설명하겠습니다 : 각각의 새로운 점 (또는 새로운 래스터 셀)에 대해 그 값을 다음과 같이 계산해야합니다. 각 이웃의 값을 가져옵니다. 이러한 각 값은 새로운 점에 특정 값을 줄 가능성이 있습니다. 예를 들어, 한 이웃이 값 202를 갖는 경우, 값 3 (가중치 1) 또는 값 11 (가중치 5)을 제공합니다. 우리는 4 명의 이웃 모두를 요약하고 새로운 가치를 발견합니다. 이것이 분명한지 확실하지 않습니다 ...
Stéphane Henriod

PS : 새 값을 찾을 수있는 계산은, 어떤 경우에는 래스터 방식을 버릴 수 2 개 속성뿐만 아니라 하나를 기반으로 할 수 있습니다
스테판 Henriod

가중치 합계의 경우 두 개의 래스터가 필요합니다. 하나는 가중치의 곱과 값을 다시 샘플링하는 것이고 다른 하나는 가중치 만 다시 샘플링하는 것입니다. 첫 번째를 두 번째로 나누면 가중 합계를 얻습니다.
radouxju

1
@ StéphaneHenriod-제안으로, 이러한 추가 사양을 추가하기 위해 질문을 편집하는 것을 고려할 수 있습니다. 초기 질문을 감안할 때이 대답은 많은 의미가 있다고 생각하지만이 새로운 정보를 사용하면 Barbarossa의 대답이 좋아 보입니다.
nicksan

2

도와 주셔서 감사합니다!

나는 마침내이 문제를 해결하기위한 비-비법적인 방법을 찾았다 ... 실제로 가장 많은 계산 시간이 걸린 것은 각 지점의 4 개의 이웃을 찾는 것이었다. X 및 Y 속성을 사용하는 대신 (아키 커서 또는 파이썬 사전과 같은 다른 데이터 구조 내에서) ArcGIS 도구 Generate near table을 사용했습니다 . 나는 이것이 공간 인덱스를 이용하고 인덱스를 직접 구현하지 않고도 성능이 훨씬 훨씬 높다고 가정합니다.


0

커서의 문제점은 한 가지 방법으로 만 순환 할 수 있으며 되돌아 갈 수 없다는 것입니다. 권장하지는 않지만 다시 방문 할 계획이라면 구조물에 구조물을 채울 수 있습니다.

단일 루프에서 기능을 처리 할 수 ​​있다면 재활용을 사용하는 것이 좋습니다. 검색 기능 클래스 함수의 매개 변수로, 파이썬은 이전 기능에 의해 할당 된 메모리를 재사용하고 커서에서 기능을 훨씬 빠르게 탐색 할 수 있습니다. 그리드를 80 % 빠르게 처리 할 수 ​​있습니다.

문제는 커서에서 검색된 기능을 저장하려는 경우 재활용을 사용할 수 없다는 것입니다.


이 "재활용 커서"주제를 탐색하고 싶지만 ESRI 도움말에서 문서를 찾을 수 없습니다. 당신은 링크가 있습니까? 검색 커서에는 재순환 매개 변수가 없습니다. Select_by_Attribute에는 이러한 매개 변수가 없습니다. ENV에는 아무것도 보이지 않습니다.
klewis


1
"커서 재사용"은 ArcPy를 통해 사용할 수 있다고 생각하지 않으며 핵심 Arcobject 만 있습니다.
klewis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.