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)

"""
Explanation: Table of Contents
<p><div class="lev1 toc-item"><a href="#Introdução-ao-NumPy-no-ambiente-Adessowiki" data-toc-modified-id="Introdução-ao-NumPy-no-ambiente-Adessowiki-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Introdução ao NumPy no ambiente Adessowiki</a></div><div class="lev2 toc-item"><a href="#O-tipo-ndarray" data-toc-modified-id="O-tipo-ndarray-11"><span class="toc-item-num">1.1&nbsp;&nbsp;</span>O tipo ndarray</a></div><div class="lev1 toc-item"><a href="#Manipulação-de-arrays" data-toc-modified-id="Manipulação-de-arrays-2"><span class="toc-item-num">2&nbsp;&nbsp;</span>Manipulação de arrays</a></div><div class="lev2 toc-item"><a href="#Criando-arrays-inicializados" data-toc-modified-id="Criando-arrays-inicializados-21"><span class="toc-item-num">2.1&nbsp;&nbsp;</span>Criando arrays inicializados</a></div><div class="lev2 toc-item"><a href="#Criando-arrays-com-valores-sequenciais" data-toc-modified-id="Criando-arrays-com-valores-sequenciais-22"><span class="toc-item-num">2.2&nbsp;&nbsp;</span>Criando arrays com valores sequenciais</a></div><div class="lev2 toc-item"><a href="#Documentação-Oficial-Numpy" data-toc-modified-id="Documentação-Oficial-Numpy-23"><span class="toc-item-num">2.3&nbsp;&nbsp;</span>Documentação Oficial Numpy</a></div>

# Introdução ao NumPy no ambiente Adessowiki

## O tipo ndarray

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).
End of explanation
"""


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)

"""
Explanation: 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.
End of explanation
"""


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)

%timeit a = np.zeros((1000000,))

%timeit a = np.empty((1000000,))

"""
Explanation: Manipulação de arrays
Criando arrays inicializados
É 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.
End of explanation
"""


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 ))

"""
Explanation: 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.
Criando arrays com valores sequenciais
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:
End of explanation
"""


