| | | |

Algoritmos e Programação I

5 Arranjos e matrizes

Compre o e-book deste material aqui! Consulte outras formas de colaborar.

5.3 Arranjos multidimensionais

Um arranjo numpy.array é um tabelamento de elementos de um mesmo tipo. Os elementos são organizados por eixos indexados (em inglês, axes). Enquanto que nas seções anteriores nos restringimos a arrays unidimensionais (de apenas um eixo), aqui, vamos estudar a alocação e manipulação de arranjos de vários eixos.

5.3.1 Alocação, indexação e fatiamento

A alocação de um numpy.array com mais de um eixo pode ser feita usando-se de listas encadeadas. Por exemplo,

1import numpy as np
2a = np.array([[1,2,3],[4,5,6]])
3a
array([[1, 2, 3],
       [4, 5, 6]])

cria o arranjo a de dois eixos, enquanto

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

cria o arranjo b de três eixos. Para fazer um paralelo com a matemática, o arranjo a é similar (mas, não equivalente) a matriz A=[ai,j]i,j=12,3

A=[123456], (5.63)

e o arranjo b é similar (mas, não equivalente) ao tensor B=[bi,j,k]i,j,k=12,2,2.

A propriedade .shape é um tuple contendo o tamanho de cada eixo. Por exemplo,

1a.shape
(2, 3)
1a.shape[0]
2

informa que a tem dois eixos, o primeiro com tamanho 2 e o segundo com tamanho 3. Um paralelo com matrizes, dizemos que a tem duas linhas e três colunas. No caso do arranjo b, temos

1b.shape
(2, 2, 2)
1b.shape[2]
2

o que nos informa tratar-se de um array de três eixos, cada um com tamanho 2.

O número total de elementos de um array pode ser obtido do atributo numpy.ndarray.size. Por exemplo,

1a.size, b.size
(6, 8)

Os elementos em um arranjo são indexados por eixos e o fatiamento também pode ser feito por eixos. Por exemplo,

1a[1,0]
4
1a[0]
array([1, 2, 3])
1a[:,1]
array([2, 5])
1a[:,2:]
array([[3],
       [6]])
1a[1,::-1]
array([6, 5, 4])

No caso do arranjo b de três eixos, temos

1b[1,1,0]
-3
1b[0,1]
array([3, 4])
1b[1,0,::-1]
array([-2, -1])

5.3.2 Inicialização

O NumPy conta com várias funções para a inicialização de arrays, algumas das mais usadas são:

  • numpy.zeros inicialização com zeros

    1np.zeros((2,3))
    array([[0., 0., 0.],
           [0., 0., 0.]])
  • numpy.ones inicialização com uns

    1np.ones((2,3,2))
    array([[[1., 1.],
            [1., 1.],
            [1., 1.]],
           [[1., 1.],
            [1., 1.],
            [1., 1.]]])
  • numpy.empty inicialização com valor da memória

    1np.empty((2,1))
    array([[5.73021895e-300],
           [6.95260453e-310]])

Observamos que o tamanho dos eixos é passado por um tuple.

5.3.3 Manipulação

O NumPy contém várias funções para a manipulação de arrays. Algumas das mais usadas são:

  • numpy.reshape reformatação de um arranjo.

    1a = np.array([[1,2,3],[4,5,6]])
    2a.reshape(3,2)
    array([[1, 2],
           [3, 4],
           [5, 6]])
    1a.reshape(-1)
    array([1, 2, 3, 4, 5, 6])
  • numpy.concatenate concatena um tuple de arranjos.

    1a = np.array([1,2,3])
    2b = np.array([4,5,6])
    3np.concatenate((a,b))
    array([1, 2, 3, 4, 5, 6])
    1a = a.reshape(1,-1)
    2b = b.reshape(1,-1)
    3np.concatenate((a,b))
    array([[1, 2, 3],
           [4, 5, 6]])
    1np.concatenate((a,b), axis=1)
    array([[1, 2, 3, 4, 5, 6]])

5.3.4 Operações e funções elementares

De forma análoga a arranjos unidimensionais, as operações aritméticas e funções elementares são aplicadas elemento-a-elementos em um arranjo. Por exemplo,

1a = np.array([[0.,1/6],[1/4,1/3]])
2b = np.array([[0.,6],[4,3]])
3np.sin(np.pi*a*b)
array([[0.0000000e+00, 1.2246468e-16],
       [1.2246468e-16, 1.2246468e-16]])

Multiplicação matriz-vetor

Dada uma matriz A=[ai,j]i,j=1n,m e um vetor 𝒙=(xi)i=1m, a multiplicação matriz-vetor A𝒙 é definida por

A𝒙=[a1,1a1,2a1,ma2,1a2,2a2,man,1an,2an,m][x1x2xm] (5.72)
=[a1,1x1+a1,2x2++a1,mxma2,1x1+a2,2x2++a2,mxman,1x1+an,2x2++an,mxm] (5.77)
Exemplo 5.3.1.

Considere a matriz

A=[112213021] (5.78)

e o vetor 𝒙=(1,2,1). A multiplicação matriz-vetor é

A𝒙=[112213021][121] (5.85)
=(1,3,5) (5.86)
1import numpy as np
2
3def MatrizVetor(A, x):
4  n,m = A.shape
5  y = np.empty(n)
6  for i in range(n):
7    y[i] = 0.
8    for j in range(m):
9      y[i] += A[i,j]*x[j]
10  return y
11
12A = np.array([[1, -1, 2],
13              [2,  1, 3],
14              [0,  2, 1]])
15x = np.array([-1, 2, 1])
16print(MatrizVetor(A,x))

Multiplicação matriz-matriz

Dadas matrizes A=[ai,j]i,j=1n,p e B=[bi,j]i,j=1p,m, a multiplicação matriz-matriz AB é a matriz AB=C=[ci,j]i,j=1n,m de elementos

ci,j=k=1pai,kbk,j. (5.87)
Exemplo 5.3.2.

Consideramos as matrizes

A=[112213021] (5.88)
B=[201202] (5.89)

A multiplicação matriz-matriz AB é

AB=[112213021][201202] =[125826] (5.99)
1def MatrizMatriz(A, B):
2  n,p = A.shape
3  m = B.shape[1]
4  C = np.empty((n,m))
5  for i in range(n):
6    for j in range(m):
7      C[i,j] = 0.
8      for k in range(p):
9        C[i,j] += A[i,k]*B[k,j]
10  return C
11
12A = np.array([[1, -1, 2],
13              [2,  1, 3],
14              [0,  2, 1]])
15B = np.array([[2, 0],
16              [1, 2],
17              [0, 2]])
18print(MatrizMatriz(A,B))

5.3.5 Exercícios

E. 5.3.1.

Complete as lacunas.

  1. a)

    A alocação de numpy.array com mais de um eixo pode ser feita usando-se de listas encadeadas.

  2. b)

    A propriedade .shape de um numpy.array é um tuple contendo o tamanho de cada eixo.

  3. c)

    O atributo .size é o número total de objetos de um numpy.array.

  4. d)

    O método numpy.reshape permite a reformatação de um numpy.array.

Resposta.

a) encadeadas; b) tuple; c) .size; d) numpy.reshape

E. 5.3.2.

Aloque o arranjo que corresponde a matriz

A=[214032157236] (5.100)

Sem implementar, forneça a saída das seguintes instruções:

  1. a)

    A[2,1]

  2. b)

    A[0,2]

  3. c)

    A[-2,-2]

  4. d)

    A[3]

  5. e)

    A[3:,:]

  6. f)

    A[:,2]

  7. g)

    A[:,1:2]

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.3.

Considere o arranjo

1A = np.array([[[-1,2,0],
2               [3,-2,1],
3               [1,-4,2]],
4              [[2,-1,0],
5               [5,-2,0],
6               [2,6,3]],
7              [[1,-1,0],
8               [7,-2,4],
9               [2,-2,1]]])

Sem implementar, forneça a saída das seguintes instruções:

  1. a)

    A[2,0,1]

  2. b)

    A[1,1,0]

  3. c)

    A[2]

  4. d)

    A[1,2]

  5. e)

    A[1:,:2,2]

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.4.

Considere o arranjo

1a = np.array([[1,2],[5,8],[2,6]])
2a
array([[1, 2],
       [5, 8],
       [2, 6]])

Sem implementar, escreva os seguintes arranjos derivados:

  1. a)

    a.reshape(6)

  2. b)

    a.reshape(2,3)

  3. c)

    a.reshape(-1)

  4. d)

    a.reshape(-1,3)

  5. e)

    a.reshape(3,-1)

  6. f)

    a.reshape(4,-1)

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.5.

Considere os arranjos

1a = np.array([1,2,3]).reshape(1,-1)
2b = np.array([4,5,6]).reshape(-1,1)

Sem implementar, escreva os seguintes arranjos derivados:

  1. a)

    np.concatenate((a,b.reshape(1,-1)))

  2. b)

    np.concatenate((a.reshape(-1,1),b))

  3. c)

    np.concatenate((a,b.reshape(1,-1)), axis=1)

  4. d)

    np.concatenate((a.reshape(-1,1),b), axis=1)

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.6.

Implemente uma função que recebe uma matriz (representada por um array) e retorna a sua transposta. Teste seu código para diversas matrizes com diversos formatos.

Resposta.
1import numpy as np
2
3def Transposta(A):
4  n,m = A.shape
5  B = np.empty((m,n))
6  for i in range(n):
7    for j in range(m):
8      B[j,i] = A[i,j]
9  return B
E. 5.3.7.

Implemente uma função que compute a multiplicação vetor-matriz

𝒚=𝒙A (5.101)
:=[x1x2xn][a1,1a1,2a1,ma2,1a2,2a2,man,1an,2an,m] (5.107)

onde, por definição, 𝒚=[yj]j=1m, com elementos

yj=k=1nxkak,j. (5.108)
Resposta.

Dica: a função numpy.dot também computa a multiplicação vetor-matriz. Teste sua implementação para diferentes matriz e vetores de diferentes tamanhos.


Envie seu comentário

Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!

Opcional. Preencha seu nome para que eu possa lhe contatar.
Opcional. Preencha seu e-mail para que eu possa lhe contatar.
As informações preenchidas são enviadas por e-mail para o desenvolvedor do site e tratadas de forma privada. Consulte a política de uso de dados para mais informações.

Licença Creative Commons
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.

Algoritmos e Programação I

5 Arranjos e matrizes

Compre o e-book deste material aqui! Consulte outras formas de colaborar.

5.3 Arranjos multidimensionais

Um arranjo numpy.array é um tabelamento de elementos de um mesmo tipo. Os elementos são organizados por eixos indexados (em inglês, axes). Enquanto que nas seções anteriores nos restringimos a arrays unidimensionais (de apenas um eixo), aqui, vamos estudar a alocação e manipulação de arranjos de vários eixos.

5.3.1 Alocação, indexação e fatiamento

A alocação de um numpy.array com mais de um eixo pode ser feita usando-se de listas encadeadas. Por exemplo,

1import numpy as np
2a = np.array([[1,2,3],[4,5,6]])
3a
array([[1, 2, 3],
       [4, 5, 6]])

cria o arranjo a de dois eixos, enquanto

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

cria o arranjo b de três eixos. Para fazer um paralelo com a matemática, o arranjo a é similar (mas, não equivalente) a matriz A=[ai,j]i,j=12,3

A=[123456], (5.63)

e o arranjo b é similar (mas, não equivalente) ao tensor B=[bi,j,k]i,j,k=12,2,2.

A propriedade .shape é um tuple contendo o tamanho de cada eixo. Por exemplo,

1a.shape
(2, 3)
1a.shape[0]
2

informa que a tem dois eixos, o primeiro com tamanho 2 e o segundo com tamanho 3. Um paralelo com matrizes, dizemos que a tem duas linhas e três colunas. No caso do arranjo b, temos

1b.shape
(2, 2, 2)
1b.shape[2]
2

o que nos informa tratar-se de um array de três eixos, cada um com tamanho 2.

O número total de elementos de um array pode ser obtido do atributo numpy.ndarray.size. Por exemplo,

1a.size, b.size
(6, 8)

Os elementos em um arranjo são indexados por eixos e o fatiamento também pode ser feito por eixos. Por exemplo,

1a[1,0]
4
1a[0]
array([1, 2, 3])
1a[:,1]
array([2, 5])
1a[:,2:]
array([[3],
       [6]])
1a[1,::-1]
array([6, 5, 4])

No caso do arranjo b de três eixos, temos

1b[1,1,0]
-3
1b[0,1]
array([3, 4])
1b[1,0,::-1]
array([-2, -1])

5.3.2 Inicialização

O NumPy conta com várias funções para a inicialização de arrays, algumas das mais usadas são:

  • numpy.zeros inicialização com zeros

    1np.zeros((2,3))
    array([[0., 0., 0.],
           [0., 0., 0.]])
  • numpy.ones inicialização com uns

    1np.ones((2,3,2))
    array([[[1., 1.],
            [1., 1.],
            [1., 1.]],
           [[1., 1.],
            [1., 1.],
            [1., 1.]]])
  • numpy.empty inicialização com valor da memória

    1np.empty((2,1))
    array([[5.73021895e-300],
           [6.95260453e-310]])

Observamos que o tamanho dos eixos é passado por um tuple.

5.3.3 Manipulação

O NumPy contém várias funções para a manipulação de arrays. Algumas das mais usadas são:

  • numpy.reshape reformatação de um arranjo.

    1a = np.array([[1,2,3],[4,5,6]])
    2a.reshape(3,2)
    array([[1, 2],
           [3, 4],
           [5, 6]])
    1a.reshape(-1)
    array([1, 2, 3, 4, 5, 6])
  • numpy.concatenate concatena um tuple de arranjos.

    1a = np.array([1,2,3])
    2b = np.array([4,5,6])
    3np.concatenate((a,b))
    array([1, 2, 3, 4, 5, 6])
    1a = a.reshape(1,-1)
    2b = b.reshape(1,-1)
    3np.concatenate((a,b))
    array([[1, 2, 3],
           [4, 5, 6]])
    1np.concatenate((a,b), axis=1)
    array([[1, 2, 3, 4, 5, 6]])

5.3.4 Operações e funções elementares

De forma análoga a arranjos unidimensionais, as operações aritméticas e funções elementares são aplicadas elemento-a-elementos em um arranjo. Por exemplo,

1a = np.array([[0.,1/6],[1/4,1/3]])
2b = np.array([[0.,6],[4,3]])
3np.sin(np.pi*a*b)
array([[0.0000000e+00, 1.2246468e-16],
       [1.2246468e-16, 1.2246468e-16]])

Multiplicação matriz-vetor

Dada uma matriz A=[ai,j]i,j=1n,m e um vetor 𝒙=(xi)i=1m, a multiplicação matriz-vetor A𝒙 é definida por

A𝒙=[a1,1a1,2a1,ma2,1a2,2a2,man,1an,2an,m][x1x2xm] (5.72)
=[a1,1x1+a1,2x2++a1,mxma2,1x1+a2,2x2++a2,mxman,1x1+an,2x2++an,mxm] (5.77)
Exemplo 5.3.1.

Considere a matriz

A=[112213021] (5.78)

e o vetor 𝒙=(1,2,1). A multiplicação matriz-vetor é

A𝒙=[112213021][121] (5.85)
=(1,3,5) (5.86)
1import numpy as np
2
3def MatrizVetor(A, x):
4  n,m = A.shape
5  y = np.empty(n)
6  for i in range(n):
7    y[i] = 0.
8    for j in range(m):
9      y[i] += A[i,j]*x[j]
10  return y
11
12A = np.array([[1, -1, 2],
13              [2,  1, 3],
14              [0,  2, 1]])
15x = np.array([-1, 2, 1])
16print(MatrizVetor(A,x))

Multiplicação matriz-matriz

Dadas matrizes A=[ai,j]i,j=1n,p e B=[bi,j]i,j=1p,m, a multiplicação matriz-matriz AB é a matriz AB=C=[ci,j]i,j=1n,m de elementos

ci,j=k=1pai,kbk,j. (5.87)
Exemplo 5.3.2.

Consideramos as matrizes

A=[112213021] (5.88)
B=[201202] (5.89)

A multiplicação matriz-matriz AB é

AB=[112213021][201202] =[125826] (5.99)
1def MatrizMatriz(A, B):
2  n,p = A.shape
3  m = B.shape[1]
4  C = np.empty((n,m))
5  for i in range(n):
6    for j in range(m):
7      C[i,j] = 0.
8      for k in range(p):
9        C[i,j] += A[i,k]*B[k,j]
10  return C
11
12A = np.array([[1, -1, 2],
13              [2,  1, 3],
14              [0,  2, 1]])
15B = np.array([[2, 0],
16              [1, 2],
17              [0, 2]])
18print(MatrizMatriz(A,B))

5.3.5 Exercícios

E. 5.3.1.

Complete as lacunas.

  1. a)

    A alocação de numpy.array com mais de um eixo pode ser feita usando-se de listas encadeadas.

  2. b)

    A propriedade .shape de um numpy.array é um tuple contendo o tamanho de cada eixo.

  3. c)

    O atributo .size é o número total de objetos de um numpy.array.

  4. d)

    O método numpy.reshape permite a reformatação de um numpy.array.

Resposta.

a) encadeadas; b) tuple; c) .size; d) numpy.reshape

E. 5.3.2.

Aloque o arranjo que corresponde a matriz

A=[214032157236] (5.100)

Sem implementar, forneça a saída das seguintes instruções:

  1. a)

    A[2,1]

  2. b)

    A[0,2]

  3. c)

    A[-2,-2]

  4. d)

    A[3]

  5. e)

    A[3:,:]

  6. f)

    A[:,2]

  7. g)

    A[:,1:2]

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.3.

Considere o arranjo

1A = np.array([[[-1,2,0],
2               [3,-2,1],
3               [1,-4,2]],
4              [[2,-1,0],
5               [5,-2,0],
6               [2,6,3]],
7              [[1,-1,0],
8               [7,-2,4],
9               [2,-2,1]]])

Sem implementar, forneça a saída das seguintes instruções:

  1. a)

    A[2,0,1]

  2. b)

    A[1,1,0]

  3. c)

    A[2]

  4. d)

    A[1,2]

  5. e)

    A[1:,:2,2]

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.4.

Considere o arranjo

1a = np.array([[1,2],[5,8],[2,6]])
2a
array([[1, 2],
       [5, 8],
       [2, 6]])

Sem implementar, escreva os seguintes arranjos derivados:

  1. a)

    a.reshape(6)

  2. b)

    a.reshape(2,3)

  3. c)

    a.reshape(-1)

  4. d)

    a.reshape(-1,3)

  5. e)

    a.reshape(3,-1)

  6. f)

    a.reshape(4,-1)

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.5.

Considere os arranjos

1a = np.array([1,2,3]).reshape(1,-1)
2b = np.array([4,5,6]).reshape(-1,1)

Sem implementar, escreva os seguintes arranjos derivados:

  1. a)

    np.concatenate((a,b.reshape(1,-1)))

  2. b)

    np.concatenate((a.reshape(-1,1),b))

  3. c)

    np.concatenate((a,b.reshape(1,-1)), axis=1)

  4. d)

    np.concatenate((a.reshape(-1,1),b), axis=1)

Resposta.

Dica: aloque o arranjo e implemente as instruções.

E. 5.3.6.

Implemente uma função que recebe uma matriz (representada por um array) e retorna a sua transposta. Teste seu código para diversas matrizes com diversos formatos.

Resposta.
1import numpy as np
2
3def Transposta(A):
4  n,m = A.shape
5  B = np.empty((m,n))
6  for i in range(n):
7    for j in range(m):
8      B[j,i] = A[i,j]
9  return B
E. 5.3.7.

Implemente uma função que compute a multiplicação vetor-matriz

𝒚=𝒙A (5.101)
:=[x1x2xn][a1,1a1,2a1,ma2,1a2,2a2,man,1an,2an,m] (5.107)

onde, por definição, 𝒚=[yj]j=1m, com elementos

yj=k=1nxkak,j. (5.108)
Resposta.

Dica: a função numpy.dot também computa a multiplicação vetor-matriz. Teste sua implementação para diferentes matriz e vetores de diferentes tamanhos.


Envie seu comentário

Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!

Opcional. Preencha seu nome para que eu possa lhe contatar.
Opcional. Preencha seu e-mail para que eu possa lhe contatar.
As informações preenchidas são enviadas por e-mail para o desenvolvedor do site e tratadas de forma privada. Consulte a política de uso de dados para mais informações.

Licença Creative Commons
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.

Pedro H A Konzen
| | | |