Индексация: с единицы, end и срезы
Как достать элемент, строку, столбец или прямоугольный кусок матрицы — и почему счёт идёт с единицы.
В MATLAB индексы начинаются с 1, а ключевое слово
endобозначает последний индекс по данному измерению.
Счёт с единицы
Это первое, что удивляет программистов, пришедших из C, Python или JavaScript: первый элемент имеет индекс 1, а не 0. Так исторически принято в математике и инженерии, и MATLAB следует этой традиции. Обращение двумерное: A(i, j) — элемент в строке i, столбце j.
A = [10 20 30; 40 50 60];
A(1,1) % 10 — первая строка, первый столбец
A(2,3) % 60 — вторая строка, третий столбец
Вывод:
ans =
10
ans =
60
end и двоеточие как «весь диапазон»
Ключевое слово end внутри индекса означает «последний». Одинокое двоеточие : означает «все элементы по этому измерению». Сочетание даёт мощный язык срезов: A(:, 2) — весь второй столбец, A(1, :) — вся первая строка, A(end, :) — последняя строка.
A = [10 20 30; 40 50 60];
col2 = A(:, 2) % весь 2-й столбец: 20; 50
row1 = A(1, :) % вся 1-я строка: 10 20 30
last = A(end, end) % правый нижний: 60
Подматрицы и присваивание
В индекс можно подставить вектор индексов — получится прямоугольный кусок. И, что важно, по индексу можно не только читать, но и писать: присваивание целому срезу меняет сразу много элементов.
A = magic(4); % известная матрица 4x4
sub = A(1:2, 3:4) % верхний правый блок 2x2
A(:, 1) = 0; % обнулить весь первый столбец
Линейная индексация
Матрицу можно адресовать и одним числом: A(5). Поскольку память column-major, счёт идёт по столбцам сверху вниз. Для матрицы 2×3 элемент A(3) — это первый элемент второго столбца. Это пригодится при логической индексации в следующем уроке.
Как работает под капотом
Когда вы пишете B = A(:, 2), MATLAB копирует данные столбца в новую переменную — здесь работает семантика copy-on-write: пока копию не меняют, реальное копирование откладывается. А вот присваивание A(:,1)=0 меняет матрицу на месте. Понимание, где создаётся копия, а где правится оригинал, помогает не удивляться, почему изменение одной переменной иногда «не задело» другую.
Индексация на службе обработки данных
Стоит увидеть индексацию как полноценный язык преобразования массивов, а не только способ достать один элемент. Перестановка строк A([2 1 3], :) меняет их порядок; A(:, end:-1:1) переворачивает столбцы зеркально; v(idx) с вектором индексов idx, полученным от sort, переупорядочивает данные согласно сортировке другого вектора. Эти приёмы постоянно встречаются в обработке сигналов и изображений: вырезать фрагмент, перевернуть, проредить, переставить — всё выражается индексацией без единого цикла. Чем свободнее вы комбинируете диапазоны, end, векторы индексов и логические маски, тем больше задач решается одной выразительной строкой, и тем ближе ваш стиль к идиоматичному MATLAB, где данные «формуются» индексацией, а не перебираются вручную.
Частые ошибки
- Индексировать с нуля:
A(0)— ошибка, индексы начинаются с 1. - Выйти за границу:
A(10)при чтении — ошибка, а при записи молча расширит матрицу нулями. - Перепутать порядок:
A(i,j)— это (строка, столбец), а не (x, y).
Удаление элементов через пустую матрицу
Индексация в MATLAB умеет не только читать и писать, но и удалять. Присваивание срезу пустой матрицы [] вырезает элементы: A(2, :) = [] удаляет вторую строку целиком, а v(v < 0) = [] выбрасывает из вектора все отрицательные значения. Это компактный идиоматичный приём очистки данных. Важно лишь, что удалять можно только согласованно — например, целую строку или столбец матрицы, а не одиночный элемент из середины (иначе матрица перестала бы быть прямоугольной).
Срезы как окно в данные
Стоит увидеть в индексации не механику доступа, а язык описания «частей» данных. A(:, end) — «последний столбец», A(1:2:end, :) — «каждая вторая строка», A(end-2:end, :) — «три последние строки». Этот словарь срезов позволяет выражать сложные выборки коротко и читаемо. В обработке данных, изображений и сигналов такие конструкции встречаются на каждом шагу: вырезать область интереса, взять каждый k-й отсчёт, отбросить краевые эффекты. Чем свободнее вы владеете срезами, тем меньше циклов появляется в вашем коде и тем он понятнее.
Итоги
- Индексы с 1;
A(i,j)— строка, столбец. :— всё измерение,end— последний индекс.- По срезу можно и читать, и присваивать; запись за границу расширяет матрицу.