O tipo ndarray, ou apenas array é um arranjo de itens homogêneos de dimensionalidade N, indexados por uma tupla de N inteiros. Existem 3 informações essenciais associadas ao ndarray: o tipo dos dados, suas dimensões e seus dados em si. A propriedade dtype permite saber o tipo de dados enquanto que shape é uma tupla que indica o tamanho de cada dimensão do arranjo. O acesso aos dados em si deve ser feito por indexação, por fatiamento ou pela variável em si.
Existem várias maneiras de criar uma variável do tipo ndarray. Por exemplo, é possível criar uma a partir de uma lista (1D) ou lista de listas usando a função array. O tipo de matriz resultante é deduzida a partir do tipo de elementos nas sequências.
Veja a seguir um vetor de inteiros com 5 elementos. Note que o vetor é uma linha com 5 colunas. Observe também que o shape é uma tupla de um único elemento (veja a vírgula que aparece por ser uma tupla).
In [14]:
import numpy as np
a = np.array( [2,3,4,-1,-2,256, 270] ,'uint8')
print ('Dimensões: a.shape=', a.shape)
print ('Tipo dos elementos: a.dtype=', a.dtype)
print ('Imprimindo o array completo:\n a=',a)
m = a.max()
print(m)
print(m.dtype)
b = a//a.max()
print (b)
Veja a seguir uma matriz bidimensional de dados ponto flutuante de 2 linhas e 3 colunas. Observe que a tupla do shape aumenta para a esquerda, isto é, se eu tiver um vetor de 3 elementos, o seu shape é (3,) e se uma nova dimensão for adicionada, por exemplo 2 linhas e 3 colunas, o shape passa a ser (3,2). O que antes shape[0] no vetor unidimensional era colunas, já na matrix bidimension shape[0] passou a ser o número de linhas. Assim o último elemento da tupla do shape indica o número de colunas, a penúltima o número de linhas. Assim se quisermos sempre buscar o número de colunas, independentemente do número de dimensões, shape[-1] informa sempre o número de colunas, shape[-2], o número de linhas.
In [19]:
b = np.array( [ [[1.5, 2.3, 5.2]],
[[4.2, 5.6, 4.4]]] )
print ('Um array bidimensional, dimensões: b.shape=', b.shape)
print ('Tipo dos elementos: b.dtype', b.dtype)
print ('Número de colunas:', b.shape[-1])
print ('Número de linhas:', b.shape[-2])
print ('Elementos, b=\n', b)
É possível criar arrays de zeros, uns ou valores não inicializados usando as funções zeros, ones ou empty. As dimensões do array são obrigatórias e é dado por uma tupla e o tipo dos elementos é opcional, sendo que o default é tipo float.
O código a seguir cria 3 arrays. O primeiro possui 2 linhas e 4 colunas. O segundo tem 3 dimensões: 3 fatias (ou imagens) onde cada uma tem 2 linhas e 5 colunas. Por último, é criado uma matriz booleana (True e False) de valores não inicializados de 2 linhas e 3 colunas. A vantagem do empty é que ele é mais rápido que o zeros ou ones. No caso abaixo, os valores mostrados na matrix criada pelo empty são aleatórios.
In [4]:
d = np.zeros( (2,4) )
print ('Array de 0s: \n', d)
d = np.ones( (3,2,5), dtype='int16' )
print ('\n\nArray de 1s: \n', d)
d = np.empty( (2,3), 'int' )
print ('Array não inicializado (valor é indeterminado):\n', d)
In [28]:
%timeit a = np.zeros((1000000,))
In [27]:
%timeit a = np.empty((1000000,))
Note que o Numpy permite arrays n-dimensionais. Em imagens em níveis de cinza iremos trabalhar com matrizes bidimensionais mas se a imagem for colorida, iremos representá-la em 3 canais, R, G e B, representados na estrutura com 3 dimensões. Se for um vídeo, isto é, uma sequência de imagens, teremos que adicionar mais uma dimensão. Se for uma tomografia, também podemos representar em 3 dimensões: largura, altura e profundidade.
As funções arange e linspace geram um vetor sequencial. Eles diferem apenas nos parâmetros. Enquanto o arange gera uma sequência a partir dos valores inicial (includente e opcional), final( excludente) e passo (opcional), linspace gera uma sequência com valores inicial e final e número de elementos. Note as diferenças nos exemplos a seguir:
In [30]:
print('np.arange( 10) = ', np.arange(10))
print('np.arange( 3, 8) = ', np.arange(3,8))
print('np.arange( 0, 2, 0.5) = ', np.arange(0, 2, 0.5))
print('np.linspace( 0, 2, 0 ) = ', np.linspace( 0, 2, 5 ))
Veja que no último caso, usando o linspace, a sequência começa em 0 e termina em 2 e deve possuir 5 elementos. Veja que para isto o passo a ser utilizado será 0.5, calculado automaticamente. Já no exemplo anterior, a sequência começa em 0 e deve terminar antes de 2 e o passo é 0.5.
In [ ]: