6. Matrizes

6.1. Criação de matrizes

Aqui vem uma boa notícia! Você já sabe criar matrizes! Em Python, o pacote mais utilizado para criar matrizes é o Numpy, que já foi utilizado no tópico anterior, e a função para criação de matrizes é np.array.

Se você está em um novo Notebook, será necessário importar novamente o pacote Numpy:

[1]:
import numpy as np

Para começar, vamos criar uma matriz com uma sequência de números de 1 a 9 e, em seguida, visualizar a matriz com a função print():

[2]:
V1 = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(V1)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Para criar esses mesmos números de forma automática, precisamos aplicar duas funções. Primeiro a dunção np.arange(), que cria uma sequência em um vetor, e, sem seguida, a função reshape(), que altera o formato de um vetor para uma matriz 3 x 3:

[3]:
V2 = np.arange(1, 10).reshape(3, 3)
print(V1)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Matrizes também podem ser criadas a partir da combinação de vetores. Considere, por exemplo, os vetores c1 e c2:

[4]:
c1 = np.array([-1, 4])
c2 = np.array([3, 2])

Com auxílio da função np.column_stack(), podemos combinar os dois vetores da seguinte forma:

[5]:
Xc = np.column_stack((c1,c2))

Repare que a função np.column_stack() combina o vetores pelas colunas. Ou seja, nesse caso, as colunas da matrix Xv serão dadas pelos vetores c1 e c2:

[6]:
print(Xc)
[[-1  3]
 [ 4  2]]

A função np.row_stack(), por sua vez, combina os vetores pelas linhas:

[7]:
Xr = np.row_stack((c1,c2))
print(Xr)
[[-1  4]
 [ 3  2]]

Alguns tipos de matrizes são muito úteis, como, por exemplo, a matriz identidade.

Podemos criá-la com a função np.eye():

[8]:
ide = np.eye(3)
print(ide)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

Também é muito útil criar uma matriz preenchida apenas com o número 1. Podemos criar uma matriz 5 x 5 (5 linhas e 5 colunas) com a função np.ones():

[9]:
uns = np.ones((5, 5))
print(uns)
[[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]]

Ou uma matriz de zeros com np.zeros:

[10]:
zeros = np.zeros((5, 5))
print(zeros)
[[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.]]

Ou ainda, uma matriz com algum elemento ou conjunto de elementos desejado, com a função np.full():

[11]:
curso = np.full((2, 2), ["Python", "Nedur"])
print(curso)
[['Python' 'Nedur']
 ['Python' 'Nedur']]

Para qualquer umas dessas matrizes, podemos checar seu tamanho utilizando a função np.shape():

[12]:
np.shape(curso)
[12]:
(2, 2)

Existem vários outros tipos de funções para criação e manipulação de matrizes, todas estão disponíveis na documentação do Numpy.

6.2. Indexação de Matrizes

As matrizes podem ser manipuladas da mesma forma que os vetores. As indexações são feitas utilizando a mesma lógica.

Para começar, vamos criar uma matriz C de dimensão 10 x 10 com números de 1 a 100:

[13]:
C = np.arange(1, 101).reshape(10, 10).T
print(C)
[[  1  11  21  31  41  51  61  71  81  91]
 [  2  12  22  32  42  52  62  72  82  92]
 [  3  13  23  33  43  53  63  73  83  93]
 [  4  14  24  34  44  54  64  74  84  94]
 [  5  15  25  35  45  55  65  75  85  95]
 [  6  16  26  36  46  56  66  76  86  96]
 [  7  17  27  37  47  57  67  77  87  97]
 [  8  18  28  38  48  58  68  78  88  98]
 [  9  19  29  39  49  59  69  79  89  99]
 [ 10  20  30  40  50  60  70  80  90 100]]

Repare que para criar a matriz começamos criando um vetor com uma sequência que começaa em 1 (incluso) e vai até 101 (não incluso), depois mudamos o formato para uma matriz 10 x 10 e, por fim, utilizamos o atributo T, que transpõe a matriz criada. Nas próximas seções trataremos de outras operações e funções com matrizes.

Para selecionar o elemento da primeira linha da segunda coluna, por exemplo, a seguinte indexação pode ser usada:

[14]:
C[0, 1]
[14]:
11

O mesmo resultado pode ser obtido com:

[15]:
C[0][1]
[15]:
11

A terceira linha da matriz C, por sua vez, pode ser selecionada com:

[16]:
C[2, : ]
[16]:
array([ 3, 13, 23, 33, 43, 53, 63, 73, 83, 93])

Ou com:

[17]:
C[2]
[17]:
array([ 3, 13, 23, 33, 43, 53, 63, 73, 83, 93])

As linhas de 2 a 4 podem ser obtidas com:

[18]:
C[1:4]
[18]:
array([[ 2, 12, 22, 32, 42, 52, 62, 72, 82, 92],
       [ 3, 13, 23, 33, 43, 53, 63, 73, 83, 93],
       [ 4, 14, 24, 34, 44, 54, 64, 74, 84, 94]])

Para selecionar apenas a primeira coluna da matriz C, a seguinte indexação pode ser usada:

[19]:
C[ : ,0]
[19]:
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

E para selecionar apenas as colunas 1 a 3:

[20]:
C[ : ,0:3]
[20]:
array([[ 1, 11, 21],
       [ 2, 12, 22],
       [ 3, 13, 23],
       [ 4, 14, 24],
       [ 5, 15, 25],
       [ 6, 16, 26],
       [ 7, 17, 27],
       [ 8, 18, 28],
       [ 9, 19, 29],
       [10, 20, 30]])

6.3. Operações com matrizes

Similarmente aos vetores, operações aritméticas e lógicas também são usadas com as matrizes.

Considere novamente a matriz C:

[21]:
print(C)
[[  1  11  21  31  41  51  61  71  81  91]
 [  2  12  22  32  42  52  62  72  82  92]
 [  3  13  23  33  43  53  63  73  83  93]
 [  4  14  24  34  44  54  64  74  84  94]
 [  5  15  25  35  45  55  65  75  85  95]
 [  6  16  26  36  46  56  66  76  86  96]
 [  7  17  27  37  47  57  67  77  87  97]
 [  8  18  28  38  48  58  68  78  88  98]
 [  9  19  29  39  49  59  69  79  89  99]
 [ 10  20  30  40  50  60  70  80  90 100]]

Multiplicar a matriz C por 10, por exemplo, significa multiplicar cada elemento da matriz por 10:

[22]:
C * 10
[22]:
array([[  10,  110,  210,  310,  410,  510,  610,  710,  810,  910],
       [  20,  120,  220,  320,  420,  520,  620,  720,  820,  920],
       [  30,  130,  230,  330,  430,  530,  630,  730,  830,  930],
       [  40,  140,  240,  340,  440,  540,  640,  740,  840,  940],
       [  50,  150,  250,  350,  450,  550,  650,  750,  850,  950],
       [  60,  160,  260,  360,  460,  560,  660,  760,  860,  960],
       [  70,  170,  270,  370,  470,  570,  670,  770,  870,  970],
       [  80,  180,  280,  380,  480,  580,  680,  780,  880,  980],
       [  90,  190,  290,  390,  490,  590,  690,  790,  890,  990],
       [ 100,  200,  300,  400,  500,  600,  700,  800,  900, 1000]])

Similarmente, dividir C por 10 significa dividir cada elemento por 10:

[23]:
C / 10
[23]:
array([[ 0.1,  1.1,  2.1,  3.1,  4.1,  5.1,  6.1,  7.1,  8.1,  9.1],
       [ 0.2,  1.2,  2.2,  3.2,  4.2,  5.2,  6.2,  7.2,  8.2,  9.2],
       [ 0.3,  1.3,  2.3,  3.3,  4.3,  5.3,  6.3,  7.3,  8.3,  9.3],
       [ 0.4,  1.4,  2.4,  3.4,  4.4,  5.4,  6.4,  7.4,  8.4,  9.4],
       [ 0.5,  1.5,  2.5,  3.5,  4.5,  5.5,  6.5,  7.5,  8.5,  9.5],
       [ 0.6,  1.6,  2.6,  3.6,  4.6,  5.6,  6.6,  7.6,  8.6,  9.6],
       [ 0.7,  1.7,  2.7,  3.7,  4.7,  5.7,  6.7,  7.7,  8.7,  9.7],
       [ 0.8,  1.8,  2.8,  3.8,  4.8,  5.8,  6.8,  7.8,  8.8,  9.8],
       [ 0.9,  1.9,  2.9,  3.9,  4.9,  5.9,  6.9,  7.9,  8.9,  9.9],
       [ 1. ,  2. ,  3. ,  4. ,  5. ,  6. ,  7. ,  8. ,  9. , 10. ]])

Faça o teste também com C + 10 e C - 10:

[24]:
C + 10
[24]:
array([[ 11,  21,  31,  41,  51,  61,  71,  81,  91, 101],
       [ 12,  22,  32,  42,  52,  62,  72,  82,  92, 102],
       [ 13,  23,  33,  43,  53,  63,  73,  83,  93, 103],
       [ 14,  24,  34,  44,  54,  64,  74,  84,  94, 104],
       [ 15,  25,  35,  45,  55,  65,  75,  85,  95, 105],
       [ 16,  26,  36,  46,  56,  66,  76,  86,  96, 106],
       [ 17,  27,  37,  47,  57,  67,  77,  87,  97, 107],
       [ 18,  28,  38,  48,  58,  68,  78,  88,  98, 108],
       [ 19,  29,  39,  49,  59,  69,  79,  89,  99, 109],
       [ 20,  30,  40,  50,  60,  70,  80,  90, 100, 110]])
[25]:
C - 10
[25]:
array([[-9,  1, 11, 21, 31, 41, 51, 61, 71, 81],
       [-8,  2, 12, 22, 32, 42, 52, 62, 72, 82],
       [-7,  3, 13, 23, 33, 43, 53, 63, 73, 83],
       [-6,  4, 14, 24, 34, 44, 54, 64, 74, 84],
       [-5,  5, 15, 25, 35, 45, 55, 65, 75, 85],
       [-4,  6, 16, 26, 36, 46, 56, 66, 76, 86],
       [-3,  7, 17, 27, 37, 47, 57, 67, 77, 87],
       [-2,  8, 18, 28, 38, 48, 58, 68, 78, 88],
       [-1,  9, 19, 29, 39, 49, 59, 69, 79, 89],
       [ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]])

Além disso, operações lógicas também podem ser usadas com as matrizes. O resultado será True (verdadeiro) ou False (falso), conforme condição utilizada:

[26]:
C >= 50
[26]:
array([[False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False, False,  True,  True,  True,  True,
         True],
       [False, False, False, False,  True,  True,  True,  True,  True,
         True]])

Para reportar os elementos da matriz baseado em uma condição específica, o seguinte código pode ser usado:

[27]:
C[C >= 50]
[27]:
array([ 51,  61,  71,  81,  91,  52,  62,  72,  82,  92,  53,  63,  73,
        83,  93,  54,  64,  74,  84,  94,  55,  65,  75,  85,  95,  56,
        66,  76,  86,  96,  57,  67,  77,  87,  97,  58,  68,  78,  88,
        98,  59,  69,  79,  89,  99,  50,  60,  70,  80,  90, 100])

Além disso, todas as mesmas funções utilizadas em vetores podem ser utilizadas em um array de qualquer dimensão:

A tabela abaixo apresenta algumas dessas funções:

Função

Descrição

np.sum()

Retorna a soma do vetor

np.min()

Retorna o valor mínimo do vetor

np.max()

Retorna o valor máximo do vetor

np.mean()

Retorna a média do vetor

np.median()

Retorna a mediana do vetor

np.var()

Retorna a variância do vetor

np.std()

Retorna o desvio padrão do vetor

Teste algumas dessas funções com a matriz C:

[28]:
print(C)
[[  1  11  21  31  41  51  61  71  81  91]
 [  2  12  22  32  42  52  62  72  82  92]
 [  3  13  23  33  43  53  63  73  83  93]
 [  4  14  24  34  44  54  64  74  84  94]
 [  5  15  25  35  45  55  65  75  85  95]
 [  6  16  26  36  46  56  66  76  86  96]
 [  7  17  27  37  47  57  67  77  87  97]
 [  8  18  28  38  48  58  68  78  88  98]
 [  9  19  29  39  49  59  69  79  89  99]
 [ 10  20  30  40  50  60  70  80  90 100]]
[29]:
np.std(C)
[29]:
28.86607004772212
[30]:
np.sum(C)
[30]:
5050

Observação:

A função np.sum também pode ser usada para somar as linhas (axis=1) ou colunas (axis=0). Observe que o atributo axis da função refere-se a uma dimensão do array multidimensional (Ndimensional array) que utilizamos tanto para vetores, quanto para matrizes (sim, você pode usar a mesma função para criar objetos multidimencionais). Veja alguns exemplos abaixo.

Para soma de colunas:

[31]:
np.sum(C, axis=0)
[31]:
array([ 55, 155, 255, 355, 455, 555, 655, 755, 855, 955])

E para a soma das linhas:

[32]:
np.sum(C, axis=1)
[32]:
array([460, 470, 480, 490, 500, 510, 520, 530, 540, 550])

6.4. Algebra matricial

No caso de matrizes, algumas operações são importantes, como obter a matriz transposta, a matriz inversa, ou fazer uma multiplicação matricial.

Para essas operações, vamos usar a matriz A:

[33]:
A = np.array([[1., 2.], [3., 4.]])
print(A)
[[1. 2.]
 [3. 4.]]

Como vimos anteriormente (na seção 6.2, ao criar a matriz C), para obter a matriz transposta de A, podemos simplemente utilizar:

[34]:
A.T
[34]:
array([[1., 3.],
       [2., 4.]])

Para obter a inversa de A:

[35]:
np.linalg.inv(A)
[35]:
array([[-2. ,  1. ],
       [ 1.5, -0.5]])

Para obter o determinante da matriz A:

[36]:
np.linalg.det(A)
[36]:
-2.0000000000000004

A multiplicação de matrizes pode ser obtida pela função np.matmul.

Para isso vamos criar um vetor B de dimensão 2x1, e, em seguida, pré-multiplicar A por B:

[37]:
B = [10, 1]
np.matmul(A,B)
[37]:
array([12., 34.])

Lembre-se de que a multiplicação de uma matriz 2x2 por um vetor 2x1 resulta em um vetor 2x1, como obtido acima. Se estiver em dúvida sobre o tamanho das matrizes que está multiplicando, utilize a função np.shape.

As funções matemáticas e estatísticas também podem ser usadas com as matrizes. As funções sum(), mean(), std(), min() e max() irão retornar a soma, média, desvio padrão, mínimo e máximo da matriz, respectivamente. Veja os exemplos abaixo com a matriz C:

[38]:
np.sum(C)
[38]:
5050
[39]:
np.mean(C)
[39]:
50.5
[40]:
np.std(C)
[40]:
28.86607004772212
[41]:
np.min(C)
[41]:
1
[42]:
np.max(C)
[42]:
100