Индексация массивов#
import numpy as np
Индексация элементов#
Доступ к отдельному элементу массива осуществляется по его индексу:
# Случай одномерного массива
x = np.arange(10)
x[2]
np.int64(2)
# Всё так же, как и со списками и кортежами Python
x[-2]
np.int64(8)
# Преобразуем в двумерный массив
x.shape = 2, 5
x
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
# Случай двумерного массива
x[1, 3]
np.int64(8)
x[1, -1]
np.int64(9)
Important
Обратите внимание, что для доступа к элементу массива указывается столько индексов, какую размерность ndim
имеет массив.
В данном случае массив двумерный и его поле ndim = 2
, поэтому указав два индекса, мы получили элемент.
Если указать, например, три индекса, то получим ошибку.
Если один - вернётся массив, соответствующий строке.
try:
# Третий индекс лишний - нет такой оси
print(x[1, 3, 2])
except IndexError as ex:
# Получаем ошибку индексации
# и соответствующее сообщение
print(ex)
too many indices for array: array is 2-dimensional, but 3 were indexed
# Указываем меньшее число индексов -
# получаем, например, вторую строку
print(x[1])
[5 6 7 8 9]
Отметим следующее:
# Результат этого
x[0, 2]
np.int64(2)
# тот же, что и результат этого
x[0][2]
np.int64(2)
Однако второй вариант более медленный, поскольку создаётся промежуточный массив x[0]
, чего не происходит в первом случае.
Срезы и обходы#
a = np.arange(10)
# Срез от 2-го до 8-го элемента с шагом 2
a[1:7:2]
array([1, 3, 5])
# Срез от предпоследнего до 11-го элемента
a[-2:10]
array([8, 9])
# Срез от 3-го с конца до 4-го с начала
# с шагом -1 (в обратном направлении)
a[-3:3:-1]
array([7, 6, 5, 4])
# Срез с 6 элемента до конца
a[5:]
array([5, 6, 7, 8, 9])
# Срез можно получить, передав в качестве индекса
# список индексов
a[[1, 5, -1]]
array([1, 5, 9])
Срезы используются, чтобы, например, изменить несколько значений в массиве:
# Заменим каждый второй элемент -1,
# начиная со второго элемента (индекс 1)
a[1::2] = -1
a
array([ 0, -1, 2, -1, 4, -1, 6, -1, 8, -1])
Если есть матрица m
, из которой требуется взять заданную строку или столбец, то это можно сделать так:
m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
m
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# Берём вторую строку
m[1]
array([4, 5, 6])
# Берём первый столбец
# (как срез по всем строкам)
m[:, 0]
array([1, 4, 7])
Способы индексации размерностей#
Создадим трёхмерный массив:
x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
x
array([[[1],
[2],
[3]],
[[4],
[5],
[6]]])
x[..., 0]
array([[1, 2, 3],
[4, 5, 6]])
# Это то же самое
x[:, :, 0]
array([[1, 2, 3],
[4, 5, 6]])
Добавить в существующий массив новую ось единичной длины возможно с помощью np.newaxis
:
x.shape
(2, 3, 1)
# Добавили новую ось как второй индекс
x[:, np.newaxis, :, :].shape
(2, 1, 3, 1)
# То же самое
x[:, None, :, :].shape
(2, 1, 3, 1)