Vetorização de NetCDF

Um dos paradigmas de paralelização, que visa minimizar o tempo de execução do código de forma eficiente, é a vetorização (vectorization). O Python tem algumas funções matemáticas padrão para operações rápidas em matrizes inteiras de dados sem ter que escrever loops. Uma dessas bibliotecas que contém tal função é numpy.

Na vetorização, as operações sobre arrays (1D, 2D, … nD) são expressas com a semântica da linguagem. A paralelização é feita pelo compilador/interpretador, ou seja, o programador não especifica como dividir o trabalho entre as unidades, seja coordenando ou juntando os resultados ao final.

Internamente, todos os elementos são armazenados em uma sequência 1D, mesmo quando há mais de uma dimensão (memória e arquivos são unidimensionais). As várias dimensões são varridas ordenadamente: “column major” (primeira dimensão é contígua, geralmente a horizontal) ou “row major” (última dimensão é contígua). Se o array tem que ser percorrido, é mais eficiente (especialmente em disco) o fazer na mesma ordem usada internamente: o acesso é sequencial, sem idas e vindas.

Fazer um loop explicitamente pode ser extremamente ineficiente, especialmente em linguagens dinâmicas. Quando operações sobre diferentes elementos do array são independentes (o que é o mais comum), podem ser paralelizadas facilmente. Todas as unidades (threads) fazem o mesmo trabalho, apenas operando sobre elementos diferentes. Na vetorização, as expressões são escritas com a operação pretendida entre as entidades (os contêineres) da mesma forma que se faz em linguagem verbal ou matemática.

Pacotes que trabalham com NetCDF

Além do pacote netcdf4, já apresentado no post sobre NetCDF, o Python possui o xarray para trabalhar com arquivos NetCDF. Os rótulos (labels) representam metadados e são estruturados em dimensões (por exemplo, tempo, latitude, …) e valores de coordenadas (por exemplo, 24-09-2018,67,064532) mais atributos. É compatível com pandas e numpy através de conversão de formatos, trabalhando também com as estruturas DataArray (array N-dimensional) e DataSet (coleção de DataArrays).

Matrizes de índices

As seleções de elementos por expressões vetoriais podem ser feitas usando-se apenas um array de índices para outro array (técnica conhecida como fancy indexing). O resultado tem a mesma dimensão que o array de índices, com os elementos correspondentes a cada posição no array de índices.

O motivo pelo qual você precisa de matrizes de coordenadas com Python/NumPy é que não há relação direta de coordenadas com valores – exceto quando suas coordenadas começam com zero e são inteiros puramente positivos, quando você pode apenas usar os índices de uma matriz como o índice. Assim, você de alguma forma precisa armazenar as coordenadas junto com seus dados. É aí que entram as grades.

O objetivo do método meshgrid do Python/NumPy é criar uma grade retangular a partir de uma matriz de valores x e uma matriz de valores y (latitudes e longitudes, por exemplo). A criação dessas grades retangulares é útil para várias tarefas. Por exemplo, aplicar uma função em um intervalo de valores para x e y.

A transposição das matrizes (método “transpose”) pode ser usado para fazer com que as linhas tenham valores de latitude constantes e as colunas, valores iguais de longitude.

Busca condicional

A função “where” do Python/NumPy retorna os índices de elementos em uma matriz de entrada onde a condição dada é satisfeita. Se apenas uma condição for fornecida, o array de saída retorna a tupla dos índices onde a condição é verdadeira. Quando usado como argumento na matriz original, retorna os valores que cumprem a condição.

O pacote xarry também possui o método where. No entanto, ele retorna o próprio array de entrada atualizado para as novas condições – por padrão, os valores que não cumprem as condições são substituídos por “nan”.

Exemplo de script

O script “vector.py”, disponível no github/viniroger, trabalha com as questões de vetorização e processamento em paralelo apresentadas aqui. Nele, um arquivo NetCDF é carregado usando xarray e são extraídas as matrizes de latitude e longitude.

O nome do arquivo serve de base para obter informações de data e horário dele. Com essas informações, são calculadas algumas grandezas astronômicas, como o ângulo zenital Z e seu cosseno, para cada ponto representados pelas matrizes de latitude e de longitude.

Outros dois métodos vão checar as condições em que os cálculos deverão ser efetuados. Por fim, a matriz será salva em um arquivo netCDF. No método “to_netcdf”, é bom incluir o parâmetro “unlimited_dims” para criar a variável “time” (mesmo que não varie no tempo), assim é possível fazer a agregação de vários arquivos, de diferentes tempos, em outros scripts.

Fontes

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.