sexta-feira, 17 de abril de 2020

Aritmética simples com NumPy

Aritmética simples com NumPy


Os operadores aritméticos podem ser usados diretamente numa matriz. Mais não podemos definir onde essa operação aritmética vai acontecer. Com a operação aritmética condicional podemos definir onde essa operação vai acontecer. A função add é um exemplo.
Nesse tutorial vamos aprender a adição, subtração, multiplicação, divisão e potenciação.

Adição

Para realizar a operação de adição utilizamos a função add. A função add soma duas matrizes e retorna uma matriz com o resultado da soma. Cada elemento da primeira matriz é somado com o elemento correspondente da segunda matriz (o primeiro elemento da primeira matriz é somado com o primeiro elemento da segunda matriz, etc).
Exemplo
import numpy as np

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

matriz = np.add(array1, array2)

print(matriz)

Subtração

A função utilizada para fazer a subtração, utilizando matrizes, é a subtract. Essa função subtrai os valores correspondes de cada matriz e retorna uma matriz com o resultado. Os elementos da segunda matriz são subtraídos dos elementos correspondentes da primeira matriz.
Exemplo
import numpy as np

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

matriz = np.subtract(array1, array2)

print(matriz)

Multiplicação

Multiply é a função utilizada para realizar multiplicações com elementos de duas matrizes.
Exemplo
import numpy as np

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

matriz = np.multiply(array1, array2)

print(matriz)

Divisão

A divisão é feita com a função divide. A função divide retorna o resultado da divisão com uma matriz de ponto flutuante.
Exemplo
import numpy as np

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

matriz = np.divide(array1, array2)

print(matriz)

Potenciação

A potenciação e feita com a função power. Power recebe duas matrizes. A primeira matriz contem os elementos base e a segunda matriz o expoente.
Exemplo
import numpy as np

array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])

matriz = np.power(array1, array2)

print(matriz)

Resto

Para saber o resto de uma divisão entre duas matrizes podemos utilizar a função mod ou remainder. As duas funções dividem os elementos da primeira matriz pelos elementos correspondentes na segunda matriz. O resultado dessas funções é uma matriz com o resto das divisões.
Exemplo com a função mod
import numpy as np

array1 = np.array([10, 8, 12])
array2 = np.array([3, 7, 5])

matriz = np.mod(array1, array2)

print(matriz)
Exemplo com a função remainder
import numpy as np

array1 = np.array([10, 8, 12])
array2 = np.array([3, 7, 5])

matriz = np.remainder(array1, array2)

print(matriz)

Quociente e resto

Se você precisar do quociente de uma divisão e o resto em matrizes separadas, você pode usar a função divmod. A função divmod recebe duas matrizes e retorna uma tupla com duas matrizes. A primeira matriz com o quociente da divisão e a segunda com o resto.
Exemplo
import numpy as np

array1 = np.array([10, 8, 12])
array2 = np.array([3, 7, 5])

matriz = np.divmod(array1, array2)

print(matriz)

Valor absoluto

O valor absoluto de um número não leva em conta a sua posição, apenas o seu valor. Para saber o valor absoluto dos elementos de uma matriz podemos utilizar a função absolute. A função absolute retorna uma matriz com o valor absoluto de cada elemento da matriz passada para a função.
Exemplo
import numpy as np

array = np.array([-2, 2, 3, -6, -12])

matriz = np.absolute(array)

print(matriz)
Note que na pratica a função absolute só retira o sinal do número.

quinta-feira, 16 de abril de 2020

Funções universais com NumPy

Funções universais com NumPy


As funções universais trabalham com objetos ndarray. E são utilizadas para a vetorização no numpy, por ser mais rápidas que a iteração dos objetos. As funções universais podem receber argumentos adicionais, como where, dtype e out. O argumento where indica onde a operação deve ocorrer. O dtype define o tipo de retorno. E out define a matriz de saída onde o retorno da função deve ser copiado.

Vetorização

Imagine que você tem duas listas, [1, 2, 3] e [4, 5, 6], e quer somar o primeiro elemento da primeira lista com o primeiro elemento da segunda lista (1 + 4). E fazer isso até o final das duas listas. Um jeito de fazer isso é iterar sobre as duas listas e somar os seus valores. A função interna do python, zip, itera sobre as duas listas e retorna uma tupla com os elementos correspondentes de cada lista: o primeiro elemento da primeira lista com o primeiro elemento da segunda lista. A função faz isso até alcançar o final das duas listas.
Com essa tupla, com os números lado a lado, só precisamos somar.
Exemplo
a = [1, 2, 3]
b = [4, 5, 6]
c = []

for i, j in zip(a, b):
  c.append(i + j)
print(c)
Utilizando a função zip o resultado seria cinco, sete e nove. Podemos obter o mesmo resultado usando a função add. Mais por que utilizar a função add? Por que a função add fornece o mesmo resultado de modo mais rápido. Isso porque a função add utiliza a vetorização ao contrario da zip que itera sobre os elementos das duas listas. A função add soma o terceiro elemento da primeira matriz com o terceiro elemento da segunda matriz, sem olhar para as outras.
Exemplo
import numpy as np
a = [1, 2, 3]
b = [4, 5, 6]
c = np.add(a, b)

print(c)

Criando sua própria função universal

Com o método frompyfunc é possível criar uma função universal. Você só precisa criar uma função normalmente e passar essa função para o método frompyfunc. O método frompyfunc recebe como parâmetros o nome da função que você acabou de criar, o numero de argumentos que essa função vai receber e o numero de objetos que essa função vai retornar. Depois disso é só atribuir o resultado do método frompyfunc a um objeto.
Exemplo
import numpy as np

def myadd(a, b):
  return a + b

myadd = np.frompyfunc(myadd, 2, 1)

print(myadd([1, 2, 3], [4, 5, 6]))

Como saber se uma função é uma função universal

Para saber se uma função é uma função universal é só utilizar a função interna do python, type. Se a função for uma função universal o valor retornado pela função type será <class numpy.ufunc="">.

Distribuição e permutação de dados com NumPy

Distribuição e permutação de dados com NumPy


Imagine que você precisa criar uma lista com valores aleatórios, mas que precisa que certos números apareçam mais vezes que outros. É possível fazer esse tipo de lista com métodos da biblioteca numpy. Esse tipo de lista é muito utilizada com data Science e estatísticas.
O módulo random têm métodos que permitem a você criar listas com números que vão aparecer mais vezes na matriz do que outros, de forma aleatória. Criando uma distribuição dos elementos na matriz de forma aleatória, mais com a densidade maior ou menor de um certo número. De acordo com a sua probabilidade.
Por exemplo, se você quer que sessenta por cento dos números de uma lista seja o número dois. A probabilidade de sair o número dois deve ser de 0,6. E se você não quer que um número apareça na lista é só definir a sua probabilidade como 0.
O método que vamos utilizar para criar essa lista é o método choice. A única diferença dos exemplos anteriores é a adição do parâmetro p, de probabilidade. Esse parâmetro recebe uma lista com a probabilidade de cada numero ser “sorteado”. Quanto maior a probabilidade, maior a chance de ele ser sorteado.
Exemplo
from numpy import random

x = random.choice([2, 4, 6, 9], p=[0.2, 0.0, 0.3, 0.5], size=(100))

print(x)
Nesse exemplo, o numero dois tem vinte por cento de chance de ser sorteado a cada novo numero. Mais isso não quer dizer que vinte por centos dos números sorteados vão ser o número dois. Significa que a quantidade de números dois vai ser próxima a vinte por cento da quantidade total de números.

Permutação de uma array

Com a permutação de uma matriz é possível embaralhar os elementos dessa matriz. A biblioteca numpy tem dois métodos para fazer a permuta: o método shuffle e permutation. O método shuffler embaralha os elementos da matriz passada como argumento e o método permutation retorna uma nova matriz, deixando a original intacta.
Exemplo
from numpy import random
import numpy as np

array = np.array([1, 2, 3, 4, 5])
# a matriz array é alterada
random.shuffle(array)

print(array)
O método permutation não alterar a matriz. Ele retorna uma nova matriz.
Exemplo
from numpy import random
import numpy as np

array = np.array([1, 2, 3, 4, 5])

# a matriz array não é alterada
print(random.permutation(array))
print(array)

quarta-feira, 15 de abril de 2020

Números aleatórios com NumPy

Números aleatórios com NumPy


Um número aleatório é um número que não foi usado uma lógica para chegar nele. Não é possível determinar como esse valor foi concebido. Mais um número aleatório não significa um novo número todas as vezes que o programa for executado. Significa que a lógica para se chegar nesse número é desconhecida. Ou que as variáveis envolvidas no processo são incalculáveis.
A maioria dos programas que geram números aleatórios usam algoritmos específicos para gerar esses números. E se existe um algoritmo pros trás desse número é possível prever qual será o número “aleatório”. Esses números são pseudoaleatórios.
É possível criar números verdadeiramente aleatórios? Sim. Para criar números verdadeiramente aleatórios é preciso usar uma fonte externa. Por exemplo, o trafego de dados da internet, movimentos do mouse e pressionamento de teclas do teclado.
Nesse tutorial vamos utilizar números pseudoaleatórios. Os números realmente aleatórios são apenas usados em aplicativos relacionados à segurança e roletas digitais.

Gerando números aleatórios

Para gerar números pseudoaleatórios utilizamos o módulo random.
Exemplo
from numpy import random

x = random.randint(100)

print(x)
Com esse exemplo a variável x vai receber um número inteiro aleatório entre 0 e 100.

Gerando números de ponto flutuante aleatórios

O método rand retorna um número aleatório com ponto flutuante entre 0 e 1.
Exemplo
from numpy import random

x = random.rand()

print(x)

Gerando matriz com números aleatórios

Os dois métodos já mostrados acimas podem retornar matrizes com números aleatórios.

Números inteiros

Para criar uma matriz com números inteiros usamos a função randint, passando o parâmetro size. O parâmetro size determina a quantidade de números aleatórios que devem ser gerados.
Exemplo
from numpy import random

x = random.randint(100, size=(6))

print(x)
O resultado será uma lista com seis números aleatórios, entre 0 e 100.

Números com ponto flutuante

Passando a quantidade de números aleatórios que se deseja para o método rand o resultado será uma lista com a quantidade de números informada.
Exemplo
from numpy import random

x = random.rand(10)

print(x)

Gerando números aleatórios a partir de uma matriz

Se for preciso escolher um número aleatório entre um numero finito de possibilidades o método choice pode ser usado. Por exemplo, se for preciso escolher um numero aleatório entre dois, quatro, seis, nove e doze. O método choice faz isso, escolhe um número entre esses informado.
Exemplo
from numpy import random

x = random.choice([2, 4, 6, 9, 12])

print(x)
Os números, entre os quais a função deve escolher, é passada numa lista.

terça-feira, 14 de abril de 2020

Matriz filtro com NumPy

Matriz filtro com NumPy


Se for preciso criar uma matriz somente com os elementos selecionado, podemos criar uma matriz que será usada como um filtro. Essa matriz é feita com uma sequência de True e False. O elemento correspondente na matriz de filtro que for True vai ser adicionado na nova matriz. Se o elemento correspondente na matriz de filtro for False esse elemento não será adicionado.
Exemplo
import numpy as np

array = np.array([1, 2, 3, 4, 5, 6])
matriz_filtro = [True, False, True, False, True, False]
novo_array = array[matriz_filtro]
print(novo_array)
O resultado apresentado será 1, 3 e 5. Isso por que os elementos da matriz filtro é true e false em sequência.

Criando uma matriz de filtro

O cenário mais comum é criar a matriz de filtro na execução do programa. Até por que se fosse pra escolher cada elemento que vai ter na matriz, seria mais fácil criar a matriz desejada logo, sem precisar criar duas matrizes. A matriz com todos os elementos e a matriz de filtro poderiam ser deixadas de lado, e criar logo a matriz com os elementos desejados.
Imagine que você precisar tirar todos os números pares de uma matriz. Esse exemplo fica fácil se todos os elementos da matriz estiverem ordenados e sem elementos faltando. Mais e se os números não estiverem ordenados, e ainda, faltando elementos da sequência? Faça uma verificação na matriz.
Exemplo
import numpy as np

array = np.array([1, 2, 7, 4, 9, 3, 8, 5])
matriz_filtro = []

for i in array:
  if i % 2 >= 1:
    matriz_filtro.append(True)
  else:
    matriz_filtro.append(False)

novo_array = array[matriz_filtro]
print(novo_array)

Ordenando elementos com NumPy

Ordenando elementos com NumPy


Ordenar os elementos de uma matriz é por os elementos em ordem. Por exemplo, a matriz [3, 7, 3, 4] é uma matriz desordenada. Uma matriz ordenada seria [3, 3, 4, 7]. Os objetos da ndarray da biblioteca numpy têm uma função chamada sort. A função sort recebe uma matriz desordenada e retorna uma matriz ordenada.
Exemplo
import numpy as np

array = np.array([1, 3, 5, 2, 4])
matriz_ordenada = np.sort(array)
print('Matriz não ordenada: ', array)
print('Matriz ordenada: ', matriz_ordenada)
Com o método sort também é possível ordenar outros tipos de dados, como a string.
Exemplo
import numpy as np

array = np.array(['banana', 'abacaxi', 'kiwi', 'melão'])
matriz_ordenada = np.sort(array)
print('Matriz ordenada: ', matriz_ordenada)
As strings são ordenadas seguindo a ordem do dicionário. Primeiro as palavras que começam com a, depois as que começam com b e assim por diante.
Se for passado uma matriz com duas dimensões os elementos serão ordenados com os elementos de sua dimensão. Assim os elementos das duas dimensões não se misturam. Cada dimensão é ordenada independente da outra.
Exemplo
import numpy as np

array = np.array([[2, 3, 1], [6, 5, 4]])
matriz_ordenada = np.sort(array)
print('Matriz ordenada: ', matriz_ordenada)
O mesmo vale para as matrizes com três ou mais dimensões.

Procurando valores numa array com NumPy

Procurando valores numa array com NumPy


A biblioteca numpy tem uma função chamada where que retorna uma tupla com os index onde a função achou elementos correspondentes à pesquisa. A busca é feita na matriz toda. Por isso se a matriz tiver mais de um numero correspondente à pesquisa o seu index vai estar na matriz.
Exemplo
import numpy as np

array = np.array([0, 1, 2, 0, 3, 4, 5, 0, 6])
a = np.where(array == 0)
print(a)
O resultado desse exemplo são os números zero, três e sete porque existem três elementos que correspondem à pesquisa e eles se encontram na posição zero, três e sete. Lembre-se que o index de uma matriz começa na posição zero.
Nesse exemplo o resultado é uma tupla com uma array indicando os index dos elementos correspondentes da pesquisa e o seu tipo de dado. No caso um inteiro de 32 bytes. Na versão do python 2.7 o resultado será apenas o index dos elementos da pesquisa.
Com a função where é possível localizar a posição de todos os números par da matriz.
Exemplo
import numpy as np

array = np.array([1, 2, 3, 4, 5, 6, 7, 8])
a = np.where(array%2 == 0)
print(a)
Também é possível localizar os números ímpares da matriz com a função where.
Exemplo
import numpy as np

array = np.array([1, 2, 3, 4, 5, 6, 7, 8])
a = np.where(array%2 == 1)
print(a)

Método Searchsorted

Searchsorted é um método que retorna o index onde um elemento deveria ser adicionado para manter uma ordem. Por exemplo, na matriz [1, 2, 5, 6] o elemento quatro deveria ser adicionado em qual index para a matriz continuar ordenada? Essa resposta você pode obter com o método searchsorted.
Exemplo
import numpy as np

array = np.array([1, 2, 5, 6])
a = np.searchsorted(array, 4)
print(a)
O método searchsorted recebe dois argumentos: a matriz onde a busca será feita e o numero que se deseja adicionar na matriz. O resultado desse exemplo é o numero dois. Porque se o numero quatro for adicionado no index dois a matriz continuará ordenada.
A função searchsorted começa a pesquisa do lado direito, do menor para o maior (na maioria dos casos). Para inverter esse comportamento podemos passar o valor do parâmetro side como right (direita). Assim a função começará a pesquisa do fim para o começo da matriz (da direita para a esquerda).
Exemplo
import numpy as np

array = np.array([1, 2, 5, 6, 8, 9])
a = np.searchsorted(array, 7, side='right')
print(a)

Múltiplos valores

A função searchsorted aceita a pesquisa por múltiplos valores. É só passar uma lista com os valores que se deseja pesquisar.
Exemplo
import numpy as np

array = np.array([1, 3, 5])
a = np.searchsorted(array, [2, 4, 6])
print(a)
O resultado da função searchsorted, quando se passa uma lista para pesquisa, é uma lista com os index das posições onde os elementos da pesquisa devem ser adicionados para a matriz continuar ordenada.