Agora você entenderá o que é NumPy!

Computação numérica, matemática e perfomance em programação

Com o nosso ambiente Python instalado e pronto, podemos então dar início aos nossos estudos com a biblioteca de computação numérica com NumPy.

*dica

Por mais que aqui estejamos abordando a análise em formato de texto através do Medium, quando você estiver no processo de desenvolvimento do seu Notebook, você pode gerar um arquivo pdf a partir do Jupyter Notebook, precisamos apenas instalar no nosso computador:

notebook do artigo

Para consultar o Jupyter Notebook que os conceitos foram abordados.

importar pacote Numpy

Vamos começar, como de praxe, chamando a palavra reservada import, com o nome do pacote e apelidá-lo.

# Importando o módulo Numpy
import numpy as np

criando estruturas de dados NumPy

Estruturas de dados são usadas para armazenar dados que depois iremos manipular, analisar, processar e assim por diante.

criar array unidimensional

A função array cria um array unidimensional, uma lista de valores que é passada dentro dos parênteses da lista — o objeto de lista em Python é delimitado dentro de colchetes.

# Criando array unidimensional
array1 = np.array([10, 20, 30, 40]); array1
array([10, 20, 30, 40])

Na sequência criamos o array2. Este array é criado com a mesma função, só que a diferença neste caso é que passamos duas listas passadas como parâmetro, logo, teremos um array bidimensional, ou seja, uma matriz.

# Criando array bi-dimensional
array2 = np.array([[100, 83, 15],[42, 78, 0]]); array2
array([[100, 83, 15],
[42, 78, 0]]
)

*dica 2

Podemos também chamar alguns atributos a partir desses objetos que acabamos de criar. Após apontar o objeto, ao adicionar o ponto + TAB, podemos navegar entre as opções disponíveis o objeto.

verificando o formato dos arrays

# Verificando o formato (shape) do array - (unidimensional)
array1.shape
(4, )
# Verificando o número de dimensões - Duas dimensões
array2.shape
(2, 3)
# Verificando o número de dimensões - Duas dimensões
array2.ndim
2

Essa é a estrutura de dados mais simples a se trabalhar. Podemos ter um array 2 x 3 como acabamos de criar, podemos ter um array 1.000 x 1.000 dependendo da quantidade de dados, do volume disponível e assim por diante. Preenchemos os arrays com os dados e depois fazemos a manipulação e processamento.

em Python tudo é objeto

Em Python tudo é objeto, com métodos e atributos. Com isso, tudo que for feito em Python, na prática, trabalharemos apenas com objetos. Seja um objeto próprio da linguagem, seja um objeto de um dos muitos pacotes da linguagem ou um objeto que o próprio usuário crie a partir da construção de uma classe. Para cada objeto temos:

método: realiza ação no objeto — função

atributo: característica do objeto — informação

Vamos chamar um dos muitos métodos disponíveis do objeto array2 que foi criado anteriormente. Cada tipo de objeto em Python tem métodos diferentes.

array2.max()
100

Já o atributo é uma informação. Nesse caso queremos obter o número de informações desse objeto com ndim

array2.ndim 
2

arange

Com NumPy também podemos criar estruturas de dados utilizando a função arange. Chamamos a função arange, indicamos entre parênteses o número de elementos da estrutura, criamos e imprimimos

array3 = np.arange(15); array3
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

Temos exatamente 15 elementos, de 0 a 14. Podemos ainda utilizar os parâmetros start e end, então criaremos uma lista de valores que comece por 0, termine por 15 e pule a cada 5.

array4 = np.arange(0, 15, 5); array4
array([0, 5, 10])

estruturas de dados linspace

Podemos ainda criar estruturas de dados com a função linspace. Essa função nos permite definir um valor de início, final e número de elementos.

# Argumentos: (start, end, elements)
array5 = np.linspace(0, 3, 4); array5
array([0., 1., 2., 3.])

estruturas de dados com outras funções

Podemos ainda criar estruturas de dados com outras funções. Podemos criar estruturas de dados com outras funções:

numpy.zeros

Podemos criar um array preenchido apenas com zeros. Isso pode ser interessante para reservar memória do computador o objeto e depois preencher o array com os números, de acordo com a necessidade.

# Array 10x8 de zeros - reservar na memória do computador o objeto para posteriormente preencherarray6 = np.zeros((10, 8)); array6
array([[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.]])

numpy.ones

Também podemos criar um array apenas de valores igual a 1.

# Array 2x3x2 de 1's - dois arrays de três linhas e duas colunasarray7 = np.ones((2, 3, 2)); array7
array([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])

numpy.eye

A função eye cria uma matriz identidade, um conceito fundamental na operação de matrizes. Uma matriz preenchida com 0, exceto na diagonal.

# Produz uma Identitiy Matrix - Matriz identidade com diagonal 1array8 = np.eye(3); array8
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]
)

numpy.diag

Criará uma matriz diagonal, a diferença é que especificamos os valores que teremos na diagonal.

# Matriz diagonal - Especificando valores da diagonalarray9 = np.diag((2,1,4,6)); array9
array([[2, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 6]]
)

pacote Random

numpy.random.rand

Podemos ainda especificar a função rand do pacote random, do NumPy. NumPy nesse contexto, é um pacote que engloba um conjunto de métodos em Python.

Dentro do NumPy, temos outro pacote — Random, que é um conjunto de métodos ou funções e, uma dessas funções, é o rand() — uma função capaz de criar valores randômicos.

# A função rand(n) produz uma sequência de números uniformemente distribuídos com range|intervalo de 0 a n# Set seed para reproduzir os mesmos exemplos
np.random.seed(100)
array10 = np.random.rand(5); #rand de 5
array10
array([0.54340494, 0.27836939, 0.42451759, 0.84477613, 0.00471886])

Foram gerados 5 valores randômicos de acordo com o parâmetro.

numpy.random.randn

Temos ainda a opção de usar a função randn. A diferença entre essa e a função anterior, é que a função randn produz uma sequência de números com distribuição normal — gaussiana.

# A função randn(n) produz uma sequência de números com distribuição normal (Gaussian)array11 = np.random.randn(5); #sequência c/ distribuição normal
aray11
array([0.35467445, -0.78606433, -0.2318722, 0.20797568, 0.93580797])

numpy.empty

Podemos ainda criar um array vazio.

# matriz três linhas vazias, duas colunas vazias
array12 = np.empty((3,2)); array12
array([[0., 0.],
[0., 0.],
[0., 0.]]
)

numpy.tile

Uma tradução direta para tile, é azulejo.

# criamos um array
np.array([[9, 4], [3, 7]])
array([[9, 4],
[3, 7]]
)
# multiplicaremos os valores desse array
np.tile(np.array([[9, 4], [3, 7]]), 10)
array([[9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4, 9, 4],
[3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3,7]]
)
# podemos manipular o sentido desse espelhamento em linhas e colunas
np.tile(np.array([[9, 4], [3, 7]]), (2,2))
array([[9, 4, 9, 4],
[3, 7, 3, 7],
[9, 4, 9, 4],
[3, 7, 3, 7]]
)

tipos de dados em NumPy

Podemos também determinar o tipo de dado que colocaremos dentro de um Array.

#lista de valores e tipo de dado
array13 = np.array([8, -3, 5, 9], dtype = 'float')
array13
array([ 8., -3., 5., 9.])

. dtype

Podemos chamar o atributo dtype para verificar exatamente quais são os tipos de dados dentro desse array

#.dtype classifica o tipo do objeto
array13.dtype
dtype('float64')
#criar array de número 14
array14 = np.array([2, 4, 6, 8]); array14
array([2, 4, 6, 8])
# dtype, por padrão é de inteiro
array14.dtype
dtype('int64')
#se um dos valores é decimal, o array é float
array15 = np.array([2.0, 4, 6, 8])
array15.dtype
dtype('float64')
array16 = np.array(['Análise','de','Dados','com Python'])
array16.dtype #U10 representa string no numpy
dtype('<U10')
#valores booleanos
array17 = np.array([True, False, True])
array17.dtype #tipo booleano|lógico
dtype('bool')
array18 = np.array([7, -3, 5.24])
array18.dtype
dtype('float64')
#.astype para tentar converter o array para outro tipo de dado array18.astype(int)
array([7,-3, 5]) # conversão realizada

operações com Arrays

Podemos ainda fazer operações com Arrays. Essa é uma das grandes vantagens de se utilizar numpy, facil manipulação. NumPy já foi pensado para computação numérica, então conseguimos rapidamente fazer operações com os objetos numéricos. Abaixo, algumas operações executadas forma extremamente simples com a biblioteca matemática:

Costumo colocar em negrito o nome da função e o output para facilitar a aborção da função e compreensão da saída.

#1. Cada elemento do array (0,30) é multiplicado por 5
array19 = np.arange(0, 30) * 5
array19
array([0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60,65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145])

#2. array fica intocável
array19 = np.arange(0, 30)
array19
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
#3. Elevando um cada elemento do array a uma potência
array20 = np.arange(6) ** 4
array([0, 1, 16, 81, 256, 625], dtype = nt32)
#4. Somando um número a cada elemento do array
array21 = np.arange(0, 30) + 1; array21
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
#5. Operações entre arrays
array22 = np.arange(0, 30,3) + 3; array22
array([3, 6, 9, 12, 15, 18, 21, 24, 27, 30])
#6.
array23 = np.arange(1,11)
array23
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
#7. Subtração de arrays - numpy facilita a manipulação de array
array22 - array23
array([2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
#8. Soma de arrays - numpy facilita a manipulação de arrays
array22 + array23
array([4, 8, 12, 16, 20, 24, 28, 32, 36, 40])
#9. Divisão de arrays - numpy facilita a manipulação de arrays
array22 / array23
array([3., 3., 3., 3., 3., 3., 3., 3., 3., 3.])
#10. Multiplicação de arrya - numpy facilita a manipulação de arrays
array22 * array23
array([3, 12, 27, 48, 75, 108, 147, 192, 243, 300])
#11. Comparar arrays elemento a elemento
array22 > array2
array([ True, True, True, True, True, True, True, True, True, True])
#12. Tabela lógica em ciência da computação
arr1 = np.array([True,False,True,False])
arr2 = np.array([False,False,True, False])
#13. Conceito de lógica - unir valores lógicos e obter resultado
np.logical_and(arr1, arr2)
array([False, False, True, False])

É possível criar arrays com Python, sem usar o módulo NumPy. Porém o NumPy é muito mais rápido.

NumPy é otimizado para performance

Para concluir, vamos provar que o NumPy é muito mais rápido do que utilizar o Python puro. Usaremos a função do Jupyter Notebook %timeit.

array_numpy = np.arange(1000)#$timeit é um comando do jupyter notebook, calcula tempo de execução
%timeit array_numpy ** 4
3.24 µs ± 28.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)------------------------------ ## ------------------------------#tempo de processamento é 100x maior
array_python = range(1000)
%timeit [array_python[i] ** 4 for i in array_python]
460 µs ± 14 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)A métrica µs significa microsegundos.

Veja que o resultado do array em NumPy foi de 3.24 microsegundos. 1 microsegundo é equivalente a 1000 nanosegundos, ou 1/1000 milisegundos, ou seja, ultrarápido. Com Python puro, temos 460 microsegundos, ou seja, pelo menos 100x mais lento do que numpy.

Utilizar o NumPy, em geral, é muito mais veloz do que utilizar o Python puro. Ele é claramente otimizado para operações matemáticas.

Obrigado.

Composing a repository of books (i bought), authors (i follow) & blogs (direct ones) for my own understanding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store