Eu tenho um código Python que foi projetado para levar shapefiles de ponto através do seguinte fluxo de trabalho:
- Mesclar pontos
- Integre pontos, de modo que quaisquer pontos a menos de 1 m um do outro se tornem um ponto
- Camada Criar recurso, onde pontos com z <10 são selecionados
- Pontos de buffer
- Resolução de polígono para varredura de 1m
- Reclassifique, onde 1 - 9 = 1; NoData = 0
Cada arquivo de forma tem aproximadamente 250.000 a 350.000 pontos, cobrindo ~ 5x7 km. Os dados dos pontos usados como entradas representam os locais da árvore. Cada ponto (isto é, árvore) tem um valor "z" associado que representa o raio da coroa e é usado no processo de buffer. Minha intenção é usar a saída binária final em um processo separado para produzir uma varredura que descreve a cobertura do dossel.
Fiz um teste com quatro shapefiles e ele produziu um raster de 700 MB e levou 35 minutos (processador i5 e 8 GB de RAM). Visto que precisarei executar esse processo em 3500 shapefiles, agradeceria qualquer conselho para simplificar o processo (consulte o código em anexo). De um modo geral, qual é a melhor maneira de lidar com o geoprocessamento de big data? Mais especificamente, existem ajustes no código ou no fluxo de trabalho que podem ajudar a aumentar a eficiência?
Editar :
Tempo (% do total) para tarefas de geoprocessamento:
- Mesclar = 7,6%
- Integrar = 7,1%
- Recurso para Lyr = 0
- Tampão = 8,8%
- Poli para Raster = 74,8%
- Reclassificar = 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")
fonte
Respostas:
Algumas alterações no algoritmo que devem ajudá-lo.
Execute sua seleção primeiro antes da mesclagem ou integração. Isso reduzirá significativamente as funções posteriores que são mais caras.
Mesclar e integrar são caros em memória, portanto, você deseja continuar eliminando recursos à medida que cria classes de recursos e tenta fazer suas mesclagens em uma árvore binária para manter o tamanho das mesclagens e integrações baixas. por exemplo, para quatro shapefiles, você mescla dois shapefiles e os integra; mesclar mais dois shapefiles e integrar; mesclar as duas classes de recursos resultantes e integrar.
Sua fila de tarefas é iniciada como uma fila de referências de shapefile. Você também tem uma fila de resultados para inserir os resultados. O método run () para o seu trabalhador de processamento paralelo fará essas operações: Retire dois itens da fila. Se nenhum item for utilizado (a fila está vazia), encerre o trabalhador. Se um item for obtido, coloque-o diretamente na fila de resultados.
Se dois itens forem utilizados, para cada item: se for um shapefile, selecione z <10 e crie uma classe de recurso in_memory; caso contrário, já é uma classe de recurso in_memory e pula a etapa de seleção. Mesclar as duas classes de recurso in_memory para criar uma nova classe de recurso in_memory. Exclua as duas classes de recurso originais. Execute a integração na nova classe de recurso. Coloque essa classe de recurso na fila de resultados.
Em seguida, execute um loop while externo. O loop começa com a fila shapefile e testa um comprimento maior que 1. Em seguida, executa a fila pelos trabalhadores. Se a fila de resultados tiver um comprimento maior que 1, o loop while executará outro processamento paralelo executado pelos trabalhadores até que a fila de resultados seja 1 classe de recurso in_memory.
Por exemplo, se você começar com 3500 shapefiles, sua primeira fila terá 3500 trabalhos. O segundo terá 1750 empregos. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. Seu grande gargalo será a memória. Se você não tiver memória suficiente (e ficará sem memória na criação da primeira fila de resultados, se for esse o caso), modifique seu algoritmo para mesclar mais de duas classes de recursos ao mesmo tempo e depois integrar, o que reduzirá o tamanho da sua primeira fila de resultados em troca de um tempo de processamento maior. Opcionalmente, você pode gravar arquivos de saída e pular usando as classes de recurso in_memory. Isso diminuirá consideravelmente a velocidade, mas superaria o gargalo da memória.
Somente após executar a mesclagem e integração em todos os arquivos de forma, terminando com uma única classe de recurso, você executa o buffer, poli para rasterizar e reclassificar. Dessa forma, essas três operações são executadas apenas uma vez e você mantém sua geometria simples.
fonte
A primeira coisa que eu faria é monitorar a utilização de recursos do seu sistema usando algo como o Monitor de Recursos no Windows 7 ou executar o Vista / XP para ter uma idéia de se você está vinculado à CPU -, memória - ou IO .
Se você tem memória ou IO, provavelmente há muito pouco a fazer, além de atualizar o hardware, reduzir o tamanho do problema ou alterar completamente a abordagem.
Se você determinar que está vinculado à CPU, eu experimentaria o
multiprocessing
módulo ou um dos muitos outros pacotes de processamento paralelo baseados em Python disponíveis para verificar se você pode usar mais núcleos de CPU para acelerar suas operações.O truque para o multiprocessamento e o paralelismo em geral é encontrar um bom esquema de particionamento que:
Você pode usar o script que criei nesta resposta como ponto de partida: Código da Porting Avenue para produzir sombras de construção no ArcPy / Python para ArcGIS Desktop?
Veja também esta postagem no blog da ESRI Geoprocessing sobre o assunto: Multiprocessamento Python - Abordagens e considerações
Eu acho que o seu caso será ainda mais desafiador devido à natureza mais "caixa preta" das ferramentas que você está usando, em vez das matrizes de geometria mais refinadas com as quais eu estava trabalhando. Talvez trabalhando com NumPy matrizes possa ser útil.
Também encontrei algum material de leitura interessante, se você quisesse ir além do arcpy:
fonte