Aula 02 - NumPy

Objetivos

  • Apresentar o objeto array de N-dimensões
  • Guia de funções sofisticadas (broadcasting)
  • Tour nos sub-módulos para: Álgebra Linear, transformada de Fourier, números aleatórios, etc
  • Uso para integrar código C/C++ e Fortran

In [ ]:
a = [0.1, 0.25, 0.03]
b = [400, 5000, 6e4]
c = a + b
c

In [ ]:
[e1+e2 for e1, e2 in zip(a, b)]

In [ ]:
import math

math.tanh(c)

In [ ]:
[math.tanh(e) for e in c]

Python é uma linguagem excelente para "propósitos gerais", com um sintaxe clara elegível, tipos de dados (data types) funcionais (strings, lists, sets, dictionaries, etc) e uma biblioteca padrão vasta.

Entretanto não é um linguagem desenhada especificamente para matemática e computação científica. Não há forma fácil de representar conjunto de dados multidimensionais nem ferramentas para álgebra linear e manipulação de matrizes. (Os blocos essenciais para quase todos os problemas de computação científica.)

Por essas razões que o NumPy existe. Em geral importamos o NumPy como np:


In [ ]:
import numpy as np

NumPy, em seu núcleo, fornece apenas um objeto array.


In [ ]:
lst = [10, 20, 30, 40]

arr = np.array([10, 20, 30, 40])

print(lst)

print(arr)

In [ ]:
print(lst[0], arr[0])
print(lst[-1], arr[-1])
print(lst[2:], arr[2:])

A diferença entre list e array é que a arrays são homógenas!


In [ ]:
lst[-1] = 'Um string'
lst

In [ ]:
arr[-1] = 'Um string'
arr

In [ ]:
arr.dtype

In [ ]:
arr[-1] = 1.234
arr

Voltando às nossas lista a e b


In [ ]:
a = [0.1, 0.25, 0.03]
b = [400, 5000, 6e4]

a = np.array(a)
b = np.array(b)
c = a + b
c

In [ ]:
np.tanh([a, b])

In [ ]:
a * b

In [ ]:
np.dot(a, b)

In [ ]:
np.matrix(a) * np.matrix(b).T

Data types

  • bool
  • uint8
  • int (Em Python2 é machine dependent)
  • int8
  • int32
  • int64
  • float (Sempre é machine dependent Matlab double)
  • float32
  • float64

(http://docs.scipy.org/doc/numpy/user/basics.types.html.)

Curiosidades...


In [ ]:
np.array(255, dtype=np.uint8)

In [ ]:
float_info = '{finfo.dtype}: max={finfo.max:<18}, approx decimal precision={finfo.precision};'
print(float_info.format(finfo=np.finfo(np.float32)))
print(float_info.format(finfo=np.finfo(np.float64)))

Criando arrays:


In [ ]:
np.zeros(3, dtype=int)

In [ ]:
np.zeros(5, dtype=float)

In [ ]:
np.ones(5, dtype=complex)

In [ ]:
a = np.empty([3, 3])
a

In [ ]:
a.fill(np.NaN)
a

Métodos das arrays


In [ ]:
a = np.array([[1, 2, 3], [1, 2, 3]])
a

In [ ]:
print('Tipo de dados             : {}'.format(a.dtype))
print('Número total de elementos : {}'.format(a.size))
print('Número de dimensões       : {}'.format(a.ndim))
print('Forma                     : {}'.format(a.shape))
print('Memória em bytes          : {}'.format(a.nbytes))

Outros métodos matemáticos/estatísticos úteis:


In [ ]:
print('Máximo e mínimo                      : {}'.format(a.min(), a.max()))
print('Some é produto de todos os elementos : {}'.format(a.sum(), a.prod()))
print('Média e desvio padrão                : {}'.format(a.mean(), a.std()))

In [ ]:
a.mean(axis=0)

In [ ]:
a.mean(axis=1)

Métodos que auxiliam na criação de arrays.


In [ ]:
np.zeros(a.shape) == np.zeros_like(a)

In [ ]:
np.arange(1, 2, 0.2)

In [ ]:
a = np.linspace(1, 10, 5)  # Olhe também `np.logspace`
a

5 amostras aleatórias tiradas da distribuição normal de média 0 e variância 1.


In [ ]:
np.random.randn(5)

5 amostras aleatórias tiradas da distribuição normal de média 10 e variância 3.


In [ ]:
np.random.normal(10, 3, 5)

Máscara condicional


In [ ]:
mask = np.where(a <= 5)  # Para quem ainda vive em MatlabTM world.
mask

In [ ]:
mask = a <= 5  # Melhor não?
mask

In [ ]:
a[mask]

Temos também as masked_arrays


In [ ]:
import numpy.ma as ma

ma.masked_array(a, mask)

Salvando e carregando novamente os dados:

  • np.save
  • np.savez
  • np.load

In [ ]:
a = np.random.rand(10)

b = np.linspace(0, 10, 10)

np.save('arquivo_a', a)

np.save('arquivo_b', b)

np.savez('arquivo_ab', a=a, b=b)

In [ ]:
%%bash

ls *.np*

In [ ]:
c = np.load('arquivo_ab.npz')

c.files

Operações: +, -, *, /, //, **, %


In [ ]:
c['b'] // c['a']

In [ ]:
a = np.array([1, 2, 3])
a **= 2
a

Manipulando dados reais

Vamos utilizar os dados do programa de observação do oceano Pirata.

http://www.goosbrasil.org/pirata/dados/


In [ ]:
np.loadtxt("./data/dados_pirata.csv", delimiter=',')

In [ ]:
!head -3 ./data/dados_pirata.csv

In [ ]:
data = np.loadtxt("./data/dados_pirata.csv", skiprows=1, usecols=range(2, 16), delimiter=',')

data.shape, data.dtype

In [ ]:
data[data == -99999.] = np.NaN
data

In [ ]:
data.max(), data.min()

In [ ]:
np.nanmax(data), np.nanmin(data)

In [ ]:
np.nanargmax(data), np.nanargmin(data)

In [ ]:
np.unravel_index(np.nanargmax(data), data.shape), np.unravel_index(np.nanargmin(data), data.shape)

In [ ]:
%matplotlib inline

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.plot(data[:, 0])
ax.plot(data[:, -1])

Dados com máscara (Masked arrays)


In [ ]:
plt.pcolormesh(data)

In [ ]:
import numpy.ma as ma

data = ma.masked_invalid(data)

In [ ]:
plt.pcolormesh(np.flipud(data.T))
plt.colorbar()

In [ ]:
data.max(), data.min(), data.mean()

In [ ]:
z = [1, 10, 100, 120, 13, 140, 180, 20, 300, 40,5, 500, 60, 80]

fig, ax = plt.subplots()
ax.plot(data[42, :], z, 'ko')
ax.invert_yaxis()