Chapter 8, Basic
Indexing and slicing
A good part of the work with arrays is to get exactly the piece you want: a value, a row, a column, a region.
Code for this chapter: básico/cap08_indexacao.py
One element, one row, one column
In multi-dimensional arrays, you separate the indices of each axis by a comma, inside a single bracket: grade[linha, coluna]. The colons (:) mean "all elements of that axis":
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]
The grade[1][2] also works, but creates an intermediate array (line 1) before getting the element, which is slower and less clear. Always prefer grade[1, 2].
Slices: `start:end:step`
As with lists, the end is excluded, negative indices count from the end, and the step can be negative. The difference is that, in the array, the slice can combine one axis at a time:
print(np.arange(10)[::3])
[0 3 6 9]
Assigning to a slice
A slice can receive a value (or another array), and the change happens in the original array. To prevent the example from altering the grid, I work on a copy:
copia = grade.copy()
copia[0, :] = 0
copia[:, 2] += 100
print(copia)
[[ 0 0 100]
[ 4 5 106]
[ 7 8 109]]
Three dimensions and the ellipsis
In arrays of 3 or more dimensions, the ellipsis (...) means "all the axes I didn't mention". It is very useful for writing code that works in any number of dimensions:
cubo = np.arange(24).reshape(2, 3, 4)
print(cubo[1, 2, 3], cubo[:, 0, :].shape, cubo[..., 0].shape)
23 (2, 4) (2, 3)
The cubo[..., 0] takes the first element of last axis, from all the others, and that's why the result has shape (2, 3).
Index out of bounds
Unlike slices, which are tolerant, an isolated index out of bounds raises an error, and the message specifies exactly which axis and what size:
try:
grade[5]
except IndexError as erro:
print(erro)
index 5 is out of bounds for axis 0 with size 3
A slice is a view, not a copy
Unlike Python lists, a slice of an array does not copy the data. It is a "window" to the same memory, and changing the slice changes the original. Chapter 10 is entirely about this, and it is what surprises most those coming from lists.
Exercise 1
The core of a matrix
Write centro(a) that returns the matrix without the borders (without the first and last row and column). For np.arange(16).reshape(4, 4), the result is [[5, 6], [9, 10]].