Capítulo 8, Básico
Indexação e fatiamento
Boa parte do trabalho com arrays é pegar exatamente o pedaço que você quer: um valor, uma linha, uma coluna, uma região.
Código deste capítulo: básico/cap08_indexacao.py
Um elemento, uma linha, uma coluna
Em arrays de várias dimensões, você separa os índices de cada eixo por vírgula, dentro de um único colchete: grade[linha, coluna]. Os dois pontos (:) significam "todos os elementos desse eixo":
import numpy as np
grade = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(grade[1, 2])
print(grade[:, 1])
print(grade[0, ::-1])
print(grade[1:, :2])
print(grade[-1])
6
[2 5 8]
[3 2 1]
[[4 5]
[7 8]]
[7 8 9]
O grade[1][2] também funciona, mas cria um array intermediário (a linha 1) antes de pegar o elemento, o que é mais lento e menos claro. Prefira sempre grade[1, 2].
Fatias: `inicio:fim:passo`
Como nas listas, o fim é excluído, os índices negativos contam do fim e o passo pode ser negativo. A diferença é que, no array, a fatia pode combinar um eixo por vez:
print(np.arange(10)[::3])
[0 3 6 9]
Atribuir a uma fatia
Uma fatia pode receber um valor (ou outro array), e a mudança acontece no array original. Para o exemplo não alterar a grade, eu trabalho em uma cópia:
copia = grade.copy()
copia[0, :] = 0
copia[:, 2] += 100
print(copia)
[[ 0 0 100]
[ 4 5 106]
[ 7 8 109]]
Três dimensões e a reticência
Em arrays de 3 ou mais dimensões, a reticência (...) significa "todos os eixos que eu não mencionei". É muito útil para escrever código que funciona em qualquer número de dimensões:
cubo = np.arange(24).reshape(2, 3, 4)
print(cubo[1, 2, 3], cubo[:, 0, :].shape, cubo[..., 0].shape)
23 (2, 4) (2, 3)
O cubo[..., 0] pega o primeiro elemento do último eixo, de todos os outros, e por isso o resultado tem forma (2, 3).
Índice fora dos limites
Diferente das fatias, que são tolerantes, um índice isolado fora do limite levanta erro, e a mensagem diz exatamente qual eixo e qual tamanho:
try:
grade[5]
except IndexError as erro:
print(erro)
index 5 is out of bounds for axis 0 with size 3
Uma fatia é uma visão, não uma cópia
Ao contrário das listas do Python, a fatia de um array não copia os dados. Ela é uma "janela" para a mesma memória, e alterar a fatia altera o original. O capítulo 10 é inteiro sobre isso, e é o que mais surpreende quem vem das listas.
Exercício 1
O miolo de uma matriz
Escreva centro(a) que devolva a matriz sem as bordas (sem a primeira e a última linha e coluna). Para np.arange(16).reshape(4, 4), o resultado é [[5, 6], [9, 10]].