Индексация: с единицы, 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 — последний индекс.
  • По срезу можно и читать, и присваивать; запись за границу расширяет матрицу.
Проверьте себя
1. С какого числа начинается индексация в MATLAB?
A0
B1
C-1
Dзависит от настроек
2. Что вернёт A(:, 2)?
AВторой элемент
BВторую строку
CВесь второй столбец
DПоследний столбец
3. Что означает end в индексе A(end, :)?
AКонец программы
BПоследний индекс по измерению (последняя строка)
CПустую матрицу
DНулевой элемент