빅 데이터를위한 Python 코드 간소화


34

다음 워크 플로를 통해 포인트 셰이프 파일을 가져 오도록 설계된 Python 코드가 있습니다.

  1. 포인트 병합
  2. 서로 1m 이내의 포인트가 하나의 포인트가되도록 포인트 통합
  3. z <10 인 점이 선택되는 피처 레이어 작성
  4. 버퍼 포인트
  5. 1m 해상도의 래스터
  6. 재 분류, 여기서 1-9 = 1; 데이터 없음 = 0

각 쉐이프 파일은 ~ 5x7 km를 덮는 약 250,000 ~ 350,000 포인트가 있습니다. 입력으로 사용 된 점 데이터는 트리 위치를 나타냅니다. 각 포인트 (즉, 트리)는 크라운 반경을 나타내며 버퍼 프로세스에 사용되는 관련 "z"값을가집니다. 내 의도는 최종 바이너리 출력을 별도의 프로세스에서 사용하여 캐노피 덮개를 설명하는 래스터를 생성하는 것입니다.

4 개의 shapefile로 테스트를 실행했으며 700MB 래스터를 생성하고 35 분이 걸렸습니다 (i5 프로세서 및 8GB RAM). 3500 셰이프 파일에서이 프로세스를 실행해야한다는 것을 알면서 프로세스를 간소화하는 조언을 부탁드립니다 (첨부 된 코드 참조). 일반적으로 빅 데이터의 지오 프로세싱을 처리하는 가장 좋은 방법은 무엇입니까? 보다 구체적으로, 효율성을 높이는 데 도움이 될 수있는 코드 또는 워크 플로우에 대한 조정이 있습니까?

편집 :

지오 프로세싱 작업을위한 시간 (전체의 %) :

  • 병합 = 7.6 %
  • 적분 = 7.1 %
  • 거짓말하는 기능 = 0
  • 버퍼 = 8.8 %
  • 폴리-래스터 = 74.8 %
  • 재 분류 = 1.6 %

여기에 이미지 설명을 입력하십시오

# Import arcpy module
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")

# Script arguments
temp4 = arcpy.GetParameterAsText(0)
if temp4 == '#' or not temp4:
    temp4 = "C:\\gdrive\\temp\\temp4" # provide a default value if unspecified

Reclassification = arcpy.GetParameterAsText(1)
if Reclassification == '#' or not Reclassification:
    Reclassification = "1 9 1;NODATA 0" # provide a default value if unspecified

Multiple_Value = arcpy.GetParameterAsText(2)
if Multiple_Value == '#' or not Multiple_Value:
    Multiple_Value = "C:\\t1.shp;C:\\t2.shp;C:\\t3.shp;C:\\t4.shp" # provide a default value if unspecified

# Local variables:
temp_shp = Multiple_Value
Output_Features = temp_shp
temp2_Layer = Output_Features
temp_Buffer = temp2_Layer
temp3 = temp_Buffer

# Process: Merge
arcpy.Merge_management(Multiple_Value, temp_shp, "x \"x\" true true false 19 Double 0 0 ,First,#,C:\\#########omitted to save space

# Process: Integrate
arcpy.Integrate_management("C:\\gdrive\\temp\\temp.shp #", "1 Meters")

# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(temp_shp, temp2_Layer, "z <10", "", "x x VISIBLE NONE;y y VISIBLE NONE;z z VISIBLE NONE;Buffer Buffer VISIBLE NONE")

# Process: Buffer
arcpy.Buffer_analysis(temp2_Layer, temp_Buffer, "z", "FULL", "ROUND", "NONE", "")

# Process: Polygon to Raster
arcpy.PolygonToRaster_conversion(temp_Buffer, "BUFF_DIST", temp3, "CELL_CENTER", "NONE", "1")

# Process: Reclassify
arcpy.gp.Reclassify_sa(temp3, "Value", Reclassification, temp4, "DATA")

3
많은 시간이 하나 또는 몇 단계로 진행되는지 여부를 확인하기 위해 일부 성능 타이밍 코드를 추가하는 것이 좋습니다. 따라서 성능 향상을 시도하고 찾는 데
집중할

5
ArcPy를 계속 사용하면 성능을 향상시킬 수있는 많은 옵션이 있다고 생각하지 않습니다. 어쩌면 다른 도구를 볼 수 있습니까? FME 또는 postgis와 같은 도구?
tmske

3
사용중인 픽셀 유형은 확실하지 않지만 "Byte"(필수) 인 경우 원시 데이터 스토리지는 래스터 당 5000x7000 = 35Mb (~ 33.4MB)이며 실제로 크지는 않습니다. 그러나 다음 차원 3500 (시간 차원)은 총 원시 크기를 ~ 114GB로 증가시킵니다.
Mike T

5
이 설명에서 알고리즘이 수행하는 작업 (또는 수행하려는 작업)을 알 수 없지만 대부분의 경우 래스터 화가 뒤 따르는 포인트 버퍼는 포인트의 래스터 화와 초점 통계 (보통 평균 또는 합계)로 대체되어야합니다. 결과는 동일하지만 긴 버퍼링 및 폴리 래스터 화 단계를 피함으로써 훨씬 빠르게 얻을 수 있습니다 . 나는 상당한 추가 속도 향상을 얻을 수 있다고 생각하지만 절차 설명의 모호성으로 인해 구체적인 조언을 제공 할 수는 없습니다.
whuber

2
점 주변의 버퍼는 가변 크기입니다 (점의 z 값을 기준으로 함). 나는 여전히 초점 통계를 수행하기 위해 결과 포인트를 z 값으로 나누고 각 세트에 대해 래스터 및 초점 통계를 수행해야합니다 (z를 통계로 최대 원형 이웃의 반경으로 사용). 그런 다음 결과를 결합하기 위해 최대 통계와 함께 9 개의 래스터에서 셀 통계를 실행하십시오. (아직 버퍼보다 ​​훨씬 빠르며 큰 데이터 세트로 래스터화할 수 있습니다.)
blord-castillo

답변:


10

도움이되는 일부 알고리즘 변경.

병합 또는 통합 전에 먼저 선택을 실행하십시오. 이것은 가장 비싼 이후 기능에서 크게 줄어 듭니다.

병합 및 통합은 메모리 비용이 많이 들기 때문에 기능 클래스를 가져올 때 기능을 계속 제거하고 2 진 트리에서 병합을 수행하여 병합 및 통합 크기를 유지하려고합니다. 예를 들어 4 개의 shapefile의 경우 2 개의 shapefile을 병합하고 통합합니다. 두 개의 shapefile을 병합하고 통합하십시오. 두 개의 결과 기능 클래스를 병합하고 통합하십시오.

작업 대기열은 shapefile 참조 대기열로 시작합니다. 결과를 넣을 결과 대기열도 있습니다. 병렬 처리 작업자의 run () 메소드는 다음 조작을 수행합니다. 큐에서 두 항목을 제거하십시오. 항목이 없으면 (큐가 비어 있음) 작업자를 종료하십시오. 하나의 항목을 가져 오면 해당 항목을 바로 결과 대기열에 넣습니다.

두 항목을 가져 오면 각 항목에 대해 : shapefile 인 경우 z <10을 선택하고 in_memory 피처 클래스를 작성하십시오. 그렇지 않으면 이미 in_memory 피처 클래스이므로 선택 단계를 건너 뜁니다. 두 개의 in_memory 기능 클래스를 병합하여 새로운 in_memory 기능 클래스를 작성하십시오. 원래 두 피처 클래스를 삭제하십시오. 새로운 기능 클래스에서 통합을 실행하십시오. 해당 기능 클래스를 결과 큐에 배치하십시오.

그런 다음 외부 while 루프를 실행하십시오. 루프는 shapefile 큐로 시작하여 1보다 큰 길이를 테스트합니다. 그런 다음 작업자를 통해 큐를 실행합니다. 결과 큐의 길이가 1보다 큰 경우 while 루프는 결과 큐가 1 in_memory 기능 클래스가 될 때까지 작업자를 통해 다른 병렬 처리 실행을 실행합니다.

예를 들어 3500 shapefile로 시작하면 첫 번째 대기열에 3500 개의 작업이 있습니다. 두 번째는 1750 개의 일자리가 있습니다. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. 큰 병목 현상은 메모리가됩니다. 메모리가 충분하지 않은 경우 (이 경우 첫 번째 결과 큐 작성시 메모리가 부족한 경우) 알고리즘을 수정하여 한 번에 2 개 이상의 피쳐 클래스를 병합 한 다음 통합하십시오. 더 긴 처리 시간과 교환되는 첫 번째 결과 큐의 크기 선택적으로, 출력 파일을 작성하고 in_memory 기능 클래스를 사용하여 건너 뛸 수 있습니다. 이렇게하면 속도가 상당히 느려지지만 메모리 병목 현상이 발생합니다.

하나의 단일 피쳐 클래스로 끝나는 모든 쉐이프 파일에 대해 병합 및 통합을 수행 한 후에 만 ​​버퍼, 폴리-래스터 및 재 분류를 수행합니까? 이렇게하면이 세 가지 작업이 한 번만 수행되며 형상이 단순 해집니다.


데이터가 메모리에 맞는 경우 in_memory 작업 공간 을 사용하려면 +1입니다 . 지오 프로세싱 작업의 속도를 크게 향상시킵니다.
RyanDalton

이것은 좋은 물건입니다. 나는 다이어그램과 일부 psuedocode (또는 실제 코드!)를 사용하면 더 나을 수 있다고 생각합니다.
blah238

예, 코드를 작성하는 데 시간이 있었기를 바랍니다. 어쨌든 새로운 병렬 처리 데모 스크립트를 작성해야합니다.
blord-castillo

14

가장 먼저 할 일은 Windows 7의 Resource Monitor 또는 Vista / XP의 perfmon 과 같은 것을 사용하여 시스템의 리소스 사용률을 모니터링하여 CPU , 메모리 또는 IO 바인딩에 대한 느낌을 얻는 것입니다 .

메모리 또는 IO 바운드 인 경우 하드웨어를 업그레이드하거나 문제 크기를 줄이거 나 접근 방식을 완전히 변경하는 것 외에는 할 수있는 일이 거의 없습니다.

CPU 바운드라고 판단되면 더 많은 CPU 코어를 사용하여 작업 속도를 높일 수 있는지 확인하기 위해 multiprocessing모듈 또는 사용 가능한 다른 많은 Python 기반 병렬 처리 패키지 중 하나를 실험 해 봅니다.

일반적으로 멀티 프로세싱 및 병렬 처리의 요령은 다음과 같은 좋은 분할 체계를 찾는 것입니다.

  1. 입력을 더 작은 작업 세트로 분할 한 다음 의미있는 방식으로 결과를 다시 조합 할 수 있습니다.
  2. 최소량의 오버 헤드를 추가합니다 (일부는 직렬 처리에 비해 피할 수 없습니다).
  3. 최적의 성능을 위해 시스템 리소스를 최대한 활용하도록 작업 세트의 크기를 조정할 수 있습니다.

이 답변에서 생성 한 스크립트를 시작점으로 사용할 수 있습니다. 건물 그림자를 ArcPy / Python for ArcGIS Desktop으로 만들기위한 번가 길 코드?

주제에 대한이 ESRI 지오 프로세싱 블로그 게시물을 참조하십시오. Python Multiprocessing – 접근 및 고려 사항

필자가 사용하고있는 더 세밀한 지오메트리 배열보다는 사용중인 도구의 "블랙 박스"특성으로 인해 귀하의 사례가 훨씬 더 어려워 질 것이라고 생각합니다. 아마도 NumPy 배열로 작업하는 것이 편리 할 것입니다.

당신이 아크 피 너머로보고 싶다면 흥미로운 독서 자료를 보았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.