Eu tenho uma classe de recurso de ponto bastante grande em um geodatabase de arquivo (~ 4 000 000 registros). Esta é uma grade regular de pontos com uma resolução de 100m.
Eu preciso executar um tipo de generalização nessa camada. Para isso, crio uma nova grade onde cada ponto fica no meio de 4 pontos "antigos":
* * * *
o o o
* * * *
o o o
* * * *
[*] = ponto da grade original - [o] = ponto da nova grade
O valor do atributo de cada novo ponto é calculado com base nos valores ponderados de seus 4 vizinhos na grade antiga. Assim, faço um loop em todos os pontos da minha nova grade e, para cada um deles, faço um loop em todos os pontos da minha grade antiga, para encontrar os vizinhos (comparando os valores de X e Y na tabela de atributos). Uma vez que quatro vizinhos foram encontrados, saímos do circuito.
Não há complexidade metodológica aqui, mas meu problema é que, com base nos meus primeiros testes, esse script durará semanas para ser concluído ...
Você vê alguma possibilidade de torná-lo mais eficiente? Algumas idéias no topo da minha cabeça:
- Indexe os campos X e Y => fiz isso, mas não percebi nenhuma alteração significativa no desempenho
- Faça uma consulta espacial para encontrar os vizinhos em vez de uma baseada em atributos. Isso realmente ajudaria? Que função espacial no ArcGIS deve fazer o trabalho? Duvido que, por exemplo, tamponar cada novo ponto seja mais eficiente
- Transforme a classe de recurso em uma matriz NumPy. Isso ajudaria? Até agora, não trabalhei muito com o NumPy e não gostaria de me aprofundar, a menos que alguém me diga que isso pode realmente ajudar a reduzir o tempo de processamento
- Algo mais?
fonte
Respostas:
E se você alimentasse os pontos em uma matriz numpy e usasse um cKDTree discreto para procurar vizinhos. Eu processo nuvens de pontos LiDAR com um grande número de pontos (> 20 milhões) em vários MINUTES usando essa técnica. Há documentação aqui para o kdtree e aqui para conversão numpy. Basicamente, você lê x, y em uma matriz e itera sobre cada ponto da matriz, encontrando índices de pontos a uma certa distância (vizinhança) de cada ponto. Você pode usar esses índices para calcular outros atributos.
fonte
Estou com Barbarossa ... os cursores do arco-íris são insanamente mancos, então eu os uso apenas para atravessar uma mesa ou aula de recurso exatamente uma vez. Se não consigo concluir o trabalho em um ciclo, uso o cursor para preencher outro tipo de estrutura de dados e trabalhar com isso.
Se você não quer se incomodar com o numpy, basta criar um dicionário python simples em que você use suas coordenadas como uma chave de texto simples e preencha os atributos necessários para o cálculo em uma lista como o valor do item do dicionário.
Em uma segunda etapa, você pode facilmente obter os valores necessários para calcular um ponto, simplesmente obtendo-os do seu dicionário (o que é incrivelmente rápido, devido ao índice de itens dos dicionários).
fonte
Para uma grade regular, deve ser muito mais eficiente trabalhar em um formato raster. Converta sua primeira grade em uma varredura, para poder reamostrar na mesma resolução usando um interpolador bilinear, mas deslocando sua imagem de saída em 1/2 pixel em X e Y e retornando novamente aos pontos, se você ainda precisar de pontos.
EDIT: para regras de decisões complexas, você pode converter cada um dos campos necessários como uma nova banda de varredura, fazer quatro cópias dessas bandas e mudar sua varredura nas 4 direções por 1/2 pixel (+50, - 50), (+ 50, + 50), (-50, -50) e (-50, + 50). Então você pode usar álgebra de mapa regular
fonte
Obrigado a todos por sua ajuda!
Finalmente encontrei uma maneira muito não-pitônica de resolver esse problema ... O que estava demorando mais tempo computacional era encontrar os quatro vizinhos de cada ponto. Em vez de usar os atributos X e Y (com um cursor arcpy ou dentro de outra estrutura de dados, como um ditionary python), acabei usando a ferramenta ArcGIS Generate near table . Suponho que isso aproveite os índices espaciais e os desempenhos são obviamente muito mais altos, sem que eu precise implementar o índice pessoalmente.
fonte
O problema com os cursores é que você pode percorrê-los de uma maneira apenas e não pode voltar. Embora não seja recomendado, você pode preencher os feautres em uma estrutura se estiver planejando revisá-los.
Se você conseguiu processar seus recursos em um único loop, sugiro ativar a reciclagem. É um parâmetro na função da classe de recurso de pesquisa que permite ao python reutilizar a memória alocada por recursos antigos e tornar mais rápido o deslocamento dos recursos em um cursor. Você pode processar sua grade 80% mais rápido.
O problema é que você não pode ativar a reciclagem se estiver planejando armazenar recursos recuperados de um cursor.
fonte