| | | | |

5.1 Arranjos

Compre o e-book deste material aqui!

Um arranjo (em inglês, array) é uma coleção de objetos (todos do mesmo tipo) em que os elementos são organizados por eixos. Nesta seção, vamos nos restringir a arranjos unidimensionais (de apenas um eixo). Esta é a estrutura computacionais usualmente utilizada para a alocação de vetores.

NumPy é uma biblioteca Python que fornece suporte para a alocação e manipulação de arranjos. Usualmente, a biblioteca é importada como segue

1import numpy as np

Na sequência, vamos assumir que o NumPy já está importado como acima.

5.1.1 Alocação de Arranjos

O método numpy.array permite a alocação de um arranjo. Como parâmetro de entrada, recebe uma list contendo os elementos do arranjo. Por exemplo,

1>>> v = np.array([-2, 1, 3])
2>>> v
3array([-2,  1,  3])
4>>> type(v)
5<class 'numpy.ndarray'>

aloca o arranjo de números inteiros v. Embora arranjos não sejam vetores, a modelagem computacional de vetores usualmente é feita utilizando-se arrays. Por exemplo, em um código Python, o vetor

𝒗=(2,1,3) (5.1)

pode ser alocado usando-se o array v acima.

O tipo dos dados de um array é definido na sua criação. Pode ser feita de forma automática ou explícita pela propriedade numpy.dtype. Por exemplo,

1>>> v = np.array([-2, 1, 3])
2>>> v.dtype
3dtype('int64')
4>>> v = np.array([-2., 1, 3])
5>>> v.dtype
6dtype('float64')
7>>> v = np.array([-2, 1, 3], dtype='float')
8>>> v.dtype
9dtype('float64')
Exemplo 5.1.1.

Aloque o vetor

𝒗=(π,1,e) (5.2)

como um array do NumPy.

1>>> import numpy as np
2>>> v = np.array([np.pi, 1, np.e])
3>>> v
4array([3.14159265, 1.        , 2.71828183])

O NumPy conta com métodos úteis para a inicialização de arrays:

  • numpy.zeros arranjo de elementos nulos

    1>>> np.zeros(3)
    2array([0., 0., 0.])
  • numpy.ones arranjo de elementos iguais a um

    1>>> np.ones(2, dtype='int')
    2array([1, 1])
  • numpy.empty arranjo de elementos não predefinidos

    1>>> np.empty(3)
    2array([4.64404327e-310, 0.00000000e+000, 6.93315702e-310])
  • numpy.linspace(start, stop, num=50) arranjo de elementos uniformemente espaçados

    1>>> np.linspace(0, 1, 5)
    2array([0.  , 0.25, 0.5 , 0.75, 1.  ])

5.1.2 Indexação e Fatiamento

Um numpy.array é uma coleção de objetos mutável, ordenada e indexada. Indexação e fatiamento podem ser feitos da mesma forma que para um tuple ou uma list. Por exemplo,

1>>> v = np.array([-1, 1, 2, 0, 3])
2>>> v[0]
3-1
4>>> v[-1]
53
6>>> v[1:4]
7array([1, 2, 0])
8>>> v[::-1]
9array([ 3,  0,  2,  1, -1])
10>>> v[3] = 4
11>>> v
12array([-1,  1,  2,  4,  3])

5.1.3 Reordenamento dos Elementos

Em programação, o reordenamento (em inglês, sorting) de elementos de uma sequência ordenada de números (array, tuple, tuple, etc.) consiste em alterar a sequência de forma que os elementos sejam organizados do menor para o mair valor. Na sequência, vamos estudar alguns métodos para isso.

Método Bolha

Dado um numpy.array3737endnote: 37Ou, um tuple, list, etc.., o método bolha consiste em percorrer o arranjo e permutar dois elementos consecutivos de forma que o segundo seja sempre maior que o primeiro. Uma vez que percorrermos o arranjo, teremos garantido que o maior valor estará na última posição do arranjo e os demais elementos ainda poderão estar desordenados. Então, percorremos o arranjo novamente, permutando elementos dois-a-dois conforme a ordem desejada, o que trará o segundo maior elemento para a penúltima posição. Ou seja, para um arranjo com n elementos, temos garantido o reordenamento de todos os elementos após n1 repetições desse algoritmo.

Exemplo 5.1.2.

Na sequência, implementamos o Método Bolha para o reordenamento de arranjos e aplicamos para

𝒗=(1,1,0,4,3). (5.3)
Código 5: bubbleSort_v1.py
1import numpy as np
2
3def bubbleSort(arr):
4  arr = arr.copy()
5  n = len(arr)
6  for k in range(n-1):
7    for i in range(n-k-1):
8      if (arr[i] > arr[i+1]):
9          arr[i], arr[i+1] = arr[i+1], arr[i]
10  return arr
11
12v = np.array([-1,1,0,4,3])
13w = bubbleSort(v)
14print(w)
Observação 5.1.1.

Em geral, para um arranjo de n elementos, o Método Bolha requer n1 repetições para completar o ordenamento. Entretanto, dependendo do caso, o ordenamento dos elementos pode terminar em menos passos.

Exemplo 5.1.3.

Na sequência, implementamos uma nova versão do Método Bolha para o reordenamento de arranjos. Esta versão verifica se há elementos fora de ordem e, caso não haja, interrompe o algoritmo. Como exemplo, aplicamos para

𝒗=(1,1,0,4,3). (5.4)
Código 6: bubbleSort_v2.py
1import numpy as np
2
3def bubbleSort(arr):
4  arr = arr.copy()
5  n = len(arr)
6  for k in range(n-1):
7    noUpdated = True
8    for i in range(n-k-1):
9      if (arr[i] > arr[i+1]):
10        arr[i], arr[i+1] = arr[i+1], arr[i]
11        noUpdated = False
12    if (noUpdated):
13      break
14  return arr
15
16v = np.array([-1,1,0,4,3])
17w = bubbleSort(v)
Observação 5.1.2.

(Métodos de Ordenamento.) Existem vários métodos para o ordenamento de uma sequência. O Método Bolha é um dos mais simples, mas também, em geral, menos eficiente. O NumPy tem disponível a função numpy.sort para o reordenamento de elementos. Também bastante útil, é a função numpy.argsort, que retorna os índices que reordenam os elementos.

5.1.4 Operações Elemento-a-Elemento

No NumPy, temos os operadores aritméticos elemento-a-elemento (em ordem de precedência)

  • **

    1>>> v = np.array([-2., 1, 3])
    2>>> w = np.array([1., -1, 2])
    3>>> v ** w
    4array([-2.,  1.,  9.])
  • *, /, //, %

    1>>> v * w
    2array([-2., -1.,  6.])
    3>>> v / w
    4array([-2. , -1. ,  1.5])
    5>>> v // w
    6array([-2., -1.,  1.])
    7>>> v % w
    8array([ 0., -0.,  1.])
  • +, -

    1>>> v + w
    2array([-1.,  0.,  5.])
    3>>> v - w
    4array([-3.,  2.,  1.])
Exemplo 5.1.4.

Vamos usar arrays para alocar os vetores

𝒗=(1.,0,2), (5.5)
𝒘=(2.,1,3). (5.6)

Então, computamos o produto interno

𝒗𝒘 :=v1w1+v2w2+v3w3 (5.7a)
=12+0(1)+(2)3 (5.7b)
=4. (5.7c)
1import numpy as np
2# vetores
3v = np.array([1., 0, -2])
4w = np.array([2., -1, 3])
5# produto interno
6vdw = np.sum(v*w)
Observação 5.1.3.

(Concatenação de Arranjos.) No NumPy, a concatenação de arranjos pode ser feita com a função numpy.concatenate. Por exemplo,

1>>> v = np.array([1,2])
2>>> w = np.array([3,4])
3>>> np.concatenate((v,w))
4array([1, 2, 3, 4])

5.1.5 Exercícios

E. 5.1.1.

Aloque cada um dos seguintes vetores como um numpy.array:

  1. a)

    𝒂=(0,2,4)

  2. b)

    𝒃=(0.1,2.7,4.5)

  3. c)

    𝒄=(e,ln(2),π)

Resposta.
1>>> import numpy as np
2>>> a = np.array([0, -2, 4])
3>>> b = np.array([0.1, -2.7, 4.5])
4>>> c = np.array([np.e, np.log(2), np.pi])
E. 5.1.2.

Considere o seguinte numpy.array

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

Sem implementar, escreva os arranjos derivados:

  1. a)

    v[1]

  2. b)

    v[1:4]

  3. c)

    v[:3]

  4. d)

    v[1:]

  5. e)

    v[1:4:2]

  6. f)

    v[-2:-5:-1]

  7. g)

    v[::-2]

Então, verifique seus resultados implementando-os.

Resposta.

Dica: consulte a Subseção 5.1.2.

E. 5.1.3.

Desenvolva uma função argBubbleSort(arr), i.e. uma função que retorna os índices que reordenam os elementos do arranjo arr em ordem crescente. Teste seu código para o ordenamento de diversos arranjos e compare os resultados com a aplicação da função numpy.argsort.

Resposta.
1import numpy as np
2
3def argBubbleSort(arr):
4  n = len(arr)
5  ind = np.arange(n)
6  for k in range(n-1):
7    noUpdated = True
8    for i in range(n-k-1):
9      if (arr[ind[i]] > arr[ind[i+1]]):
10        ind[i], ind[i+1] = ind[i+1], ind[i]
11        noUpdated = False
12    if (noUpdated):
13      break
14  return ind
E. 5.1.4.

Desenvolva um Método Bolha para o reordenamento dos elementos de um dado arranjo em ordem decrescente. Teste seu código para o reordenamento de diversos arranjos. Como pode-se usar a função numpy.sort para obter os mesmos resultados?

Resposta.
1import numpy as np
2
3def emOrdem(x, y):
4    return x < y
5
6def bubbleSort(arr, emOrdem=emOrdem):
7  arr = arr.copy()
8  n = len(arr)
9  for k in range(n-1):
10    noUpdated = True
11    for i in range(n-k-1):
12      if not(emOrdem(arr[i], arr[i+1])):
13        arr[i], arr[i+1] = arr[i+1], arr[i]
14        noUpdated = False
15    if (noUpdated):
16        break
17  return arr
E. 5.1.5.

Desenvolva uma função argBubbleSort(arr, emOrdem), i.e. uma função que retorna os índices que reordenam os elementos do arranjo arr na ordem definida pela função emOrdem. Teste seu código para o ordenamento de diversos arranjos, tanto em ordem crescente como em ordem decrescente. Como pode-se obter os mesmos resultados usando-se a função numpy.argsort?

Resposta.
1import numpy as np
2
3def argBubbleSort(arr, emOrdem=emOrdem):
4  n = len(arr)
5  ind = np.arange(n)
6  for k in range(n-1):
7    noUpdated = True
8    for i in range(n-k-1):
9      if not(emOrdem(arr[ind[i]], arr[ind[i+1]])):
10        ind[i], ind[i+1] = ind[i+1], ind[i]
11        noUpdated = False
12    if (noUpdated):
13      break
14  return ind
E. 5.1.6.

Implemente uma função media(arr) que returna o valor médio do arranjo de números arr. Teste seu código para diferentes arranjos e compare os resultados com o da função numpy.mean.

Resposta.
1import numpy as np
2
3def media(arr):
4  return np.sum(arr)/arr.size
E. 5.1.7.

Desenvolva uma função que retorna o ângulo entre dois vetores 𝒗 e 𝒘 dados.

Resposta.
1import numpy as np
2
3def dot(v, w):
4    return np.sum(v*w)
5
6def angulo(v, w):
7  # norma de v
8  norm_v = np.sqrt(dot(v,v))
9  # norma de w
10  norm_w = np.sqrt(dot(w,w))
11  # cos(theta)
12  cosTheta = dot(v,w)/(norm_v*norm_w)
13  # theta
14  theta = np.acos(cosTheta)
15  return theta

Envie seu comentário

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. Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!