Matrizes e vetores não são escritas diretamente em python. São, na verdade, armazenados na forma de listas.
Para facilitar o trabalho, utiliza-se a biblioteca numpy
, tipicamente referenciada com a sigla np
, empregando-se a propriedade arrays para armazenamento destas listas.
O numpy
possui um grande número de métodos (pacotes) de cálculos associados à listas. Algumas das mais importantes estão apresentadas a seguir (Programiz)
Objetivo | Algumas funções do numpy |
---|---|
Criação de listas | np.array(), np.zeros(), np.ones(), np.empty() |
Manipulação | np.reshape(), np.transpose() |
Funções matemáticas | np.sqrt(), np.power() |
Funções estatísticas | np.median(), np.mean(), np.std(), and np.var() |
Carrgamento, salvamento | np.save(), np.load(), np.loadtxt() |
Vejamos alguns exemplos.
Exemplo -) Escrita de Matriz
Escreva uma matriz $ A\left(i,j\right) = i+j $, de 4 por 3.
Considere por exemplo o seguinte código
import numpy as np
A = np.zeros([4,3])
for i in range(4):
for j in range(3):
A[i][j] = i+j+2
print(A)
Que gera o seguinte resultado.
[[2. 3. 4.]
[3. 4. 5.]
[4. 5. 6.]
[5. 6. 7.]]
Exemplo -) Escrevendo uma matriz com o comando reshape
Considere por exemplo o seguinte código
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]).reshape(5,4)
print(a)
Que gera o seguinte resultado.
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]
[13 14 15 16]
[17 18 19 20]]
Há algumas formas de extrair submatrizes e subvetores do python.
Forma 1 - extraindo linhas e colunas com vetores de posicao
A forma a seguir funciona com arrays do *numpy* .
a = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]).reshape(5,4)
print(a)
posl=[0,3] # vetor de posições das linhas
posc = [1,2] # vetor de posições das colunas
b = a[posl][:,posc] # vetor extraído
print(b)
Forma 2 - criando uma funcao de extracao
A forma a seguir cria extrai submatrizes e subvetores de uma lista A de duas dimensões (não precisa usar o numpy)
# Função que extrai posicões de uma lista A retangular bidimensional
def extraiposicao(A,posl,posc):
B = []
nl = len(posl);
nc = len(posc);
for i in range(nl):
B.append([])
for j in range(nc):
B[i].append(A[posl[i]][posc[j]])
return(B)
A = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] # "matriz"
posl = [0,2] # posicoes das linhas
posc = [1,3] # posicoes das colunas
B = extraiposicao(A,posl,posc)
print(B)
A transposta de matrizes e vetores é dada pela função np.tranpose()
ou escrevendo .T
associado a uma variável. Por exemplo:
a = np.array([1,2,3])
b = a.T
c = np.tranpose(a)
No código acima, b,c são iguais (mesma forma de fazer).
O comando retorna resultados distintos a depender da entrada (numpy.org):
np.array([1,2,3])
gera o mesmo vetorA[i][j]
passa a ser A[j][i]
)Um segundo argumento da função permite informar quais eixos devem ser transpostos.
Usando o numpy, é possível efetuar a multiplicação matricial com o comando np.matmul(A,B)
, ou o comando A @ B
, que multiplicad duas matrizes $\mathbf{A}$ e $\mathbf{B}$.
Considere por exemplo a seguinte multiplicação matricial
$$ \mathbf{A} = \begin{pmatrix} 1 & 2 & 3 \cr 4 & 5 & 6 \cr 7 & 8 & 9 \cr 10 & 11 & 12 \end{pmatrix} $$$$ \mathbf{B} = \begin{pmatrix} 1 & 2 & 3 & 4 \cr 5 & 6 & 7 & 8 \cr 9 & 10 & 11 & 12 \end{pmatrix} $$Fazendo:
$$ \mathbf{C} = \mathbf{A} \cdot \mathbf{B} = \begin{pmatrix} 1 & 2 & 3 \cr 4 & 5 & 6 \cr 7 & 8 & 9 \cr 10 & 11 & 12 \end{pmatrix} \cdot \begin{pmatrix} 1 & 2 & 3 & 4 \cr 5 & 6 & 7 & 8 \cr 9 & 10 & 11 & 12 \end{pmatrix} $$Em python, pode-se efeutar a multiplicação acima da seguinte forma:
A = np.array([1,2,3,4,5,6,7,8,9,10,11,12]).reshape(4,3)
B = np.array([1,2,3,4,5,6,7,8,9,10,11,12]).reshape(3,4)
v = np.array([1,2,3])
C = A @ B
print(C)
O matmul
do numpy funciona da seguinte forma:
$$ \mathbf{A} $$ | $$ \mathbf{B} $$ | Saida | Comentário |
---|---|---|---|
$$ n \times m $$ | $$ m \times p $$ | $$ n \times p $$ | Multiplicacao matricial normal |
$$ n^* $$ | $$ n^* \times p $$ | $$ p^* $$ | Se o 1º argumento é 1D, cria uma dimensão adicional, multiplica e depois colapsa a dimensão |
$$ n \times p $$ | $$ p^* $$ | $$ n^* $$ | Se o 2º argumento é 1D, cria uma dimensão adicional, multiplica e depois colapsa a dimensão |
Note que se um dos vetores que estão sendo multiplicados tiver dimensão 1, ele cria outra dimensão, efetua a multiplicação e depois colapsa a dimensão criada.
No python a multiplicação de duas 'matrizes' sem símbolos especiais é na verdade a multiplicação elemento a elemento. Ou seja:
$$ \mathbf{A} = \begin{pmatrix} 1 & 2 & 3 \cr 4 & 5 & 6 \cr 7 & 8 & 9 \cr 10 & 11 & 12 \end{pmatrix} $$$$ \mathbf{B} = \begin{pmatrix} 10 & 20 & 30 \cr 40 & 50 & 60 \cr 70 & 80 & 90 \cr 100 & 110 & 120 \end{pmatrix} $$Fazendo:
$$ \mathbf{C} = \mathbf{A} \odot \mathbf{B} = \begin{pmatrix} 1 & 2 & 3 \cr 4 & 5 & 6 \cr 7 & 8 & 9 \cr 10 & 11 & 12 \end{pmatrix} \odot \begin{pmatrix} 10 & 20 & 30 \cr 40 & 50 & 60 \cr 70 & 80 & 90 \cr 100 & 110 & 120 \end{pmatrix} = \begin{pmatrix} 1 \cdot 10 & 2\cdot 20 & 3\cdot 30 & 4 \cdot 40 \cr 5 \cdot 50 & 6 \cdot 60 & 7 \cdot 70 & 8 \cdot 80 \cr 9 \cdot 90 & 10 \cdot 100 & 11 \cdot 110 & 12 \cdot 120 \end{pmatrix} $$$$ \mathbf{C} = \begin{pmatrix} 10 & 40 & 90 \cr 160 & 250 & 360 \cr 490 & 640 & 810 \cr 1000 & 1210 & 1440 \end{pmatrix} $$No python, a multiplicação seria feita como:
A = np.array([1,2,3,4,5,6,7,8,9,10,11,12]).reshape(4,3)
B = np.array([10,20,30,40,50,60,70,80,90,100,110,120]).reshape(4,3)
C = A*B
Que gera o seguinte resultado:
array([[ 10, 40, 90],
[ 160, 250, 360],
[ 490, 640, 810],
[1000, 1210, 1440]])
A soma de listas elemento a elemento é análoga, conforme segue.
A = np.array([1,2,3,4,5,6,7,8,9,10,11,12]).reshape(4,3)
B = np.array([10,20,30,40,50,60,70,80,90,100,110,120]).reshape(4,3)
C = A + B
print(C)
Que gera o seguinte resultado.
[[ 11 22 33]
[ 44 55 66]
[ 77 88 99]
[110 121 132]]
Pode-se fazer uso de funções matemáticas associadas à listas inteiras (desde que numéricas). Este site apresenta a lista de funções matemáticas e estatísticas que estão disponíveis no numpy.
Por exemplo, considere que se deseja extrair a raiz quadrada da seguinte lista.
A = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]).reshape(5,4)
B = np.sqrt(A)
print(B)
O que gera o seguinte resultado:
[[1. 1.41421356 1.73205081 2. ]
[2.23606798 2.44948974 2.64575131 2.82842712]
[3. 3.16227766 3.31662479 3.46410162]
[3.60555128 3.74165739 3.87298335 4. ]
[4.12310563 4.24264069 4.35889894 4.47213595]]