Скаляр — это одно число: в линейной алгебре элемент поля, над которым построено векторное пространство (для практики — обычно вещественное число). Вектор — упорядоченный набор из n чисел, элемент пространства R^n. Матрица — прямоугольная таблица чисел m x n, которая задает линейное отображение из R^n в R^m. Ниже — как эти три объекта связаны, какие операции между ними определены и как они выглядят в NumPy (примеры проверены на Python 3.14.7 и NumPy 2.5.3, сентябрь 2026).
Содержание
- Мини-словарь: четыре термина, которые путают
- Скаляр, вектор, матрица: сравнение по размерности
- Минимальный пример: все три объекта в NumPy
- Операции и их результаты
- Скаляр в NumPy: 0-мерный массив, вектор длины 1 и матрица 1×1
- Две частые ошибки с векторами и матрицами
- Строка, столбец и почему
.Tу вектора ничего не делает - Выводы
- Где применяется / связь с практикой
- FAQ
Мини-словарь: четыре термина, которые путают
Слово «скаляр» встречается в нескольких близких, но разных смыслах. Разведем их сразу:
| Термин | Что это | Результат | Пример |
|---|---|---|---|
| Скаляр | одно число | число | 3, -0.5 |
| Умножение на скаляр | число умножается на каждую координату вектора | вектор | 3 * (2, -1) = (6, -3) |
| Скалярное произведение | сумма попарных произведений координат двух векторов | скаляр | (1, 2) . (3, 4) = 11 |
| Скалярная величина (физика) | величина без направления | число с единицей | масса 2 кг, температура 20 °C |
Главная ловушка: «скалярное произведение» названо так не потому, что в нем участвует скаляр, а потому, что его результат — скаляр. А «умножение на скаляр» возвращает вектор.
Скаляр, вектор, матрица: сравнение по размерности
Удобная сквозная модель — смотреть на число индексов, которые нужны, чтобы достать одно значение. Это упрощение, принятое в программировании (NumPy, PyTorch): в строгой математике вектор определяется через аксиомы векторного пространства, а не через «массив чисел».
| Объект | Индексов | Форма в NumPy (shape) | Геометрический смысл |
|---|---|---|---|
| Скаляр | 0 | () |
точка на числовой прямой, коэффициент растяжения |
| Вектор | 1 | (n,) |
направленный отрезок от начала координат |
| Матрица | 2 | (m, n) |
линейное преобразование пространства |
| Тензор (в смысле ML) | 3 и больше | (k, m, n) |
набор матриц, например пакет изображений |
Геометрически вектор (2, -1) — инструкция «сдвинуться на 2 вправо по X и на 1 вниз по Y». Скаляр 3 растягивает этот вектор в три раза, отрицательный скаляр еще и разворачивает его в противоположную сторону. Матрица поворачивает, растягивает или проецирует сразу все векторы пространства.
Минимальный пример: все три объекта в NumPy
Сначала полный рабочий пример, потом разбор по строкам.
import numpy as np
s = 3.0 # скаляр: одно число
v = np.array([2.0, -1.0, 2.0]) # вектор из R^3
A = np.array([1.0, 0.0, 2.0,
0.0, 1.0, -1.0]).reshape(2, 3) # матрица 2x3
print("ndim:", np.ndim(s), v.ndim, A.ndim)
print("shape:", np.shape(s), v.shape, A.shape)
print("s * v =", s * v) # умножение вектора на скаляр
print("v + v =", v + v) # сложение векторов
print("|v| =", np.linalg.norm(v)) # длина (евклидова норма) - скаляр
print("v . v =", v @ v) # скалярное произведение - скаляр
print("A @ v =", A @ v) # матрица 2x3 на вектор из R^3 -> R^2
Вывод:
ndim: 0 1 2
shape: () (3,) (2, 3)
s * v = [ 6. -3. 6.]
v + v = [ 4. -2. 4.]
|v| = 3.0
v . v = 9.0
A @ v = [ 6. -3.]
Что здесь произошло:
ndimпоказывает число индексов: 0 у скаляра, 1 у вектора, 2 у матрицы.s * vумножает каждую координату на 3 — результат остается вектором той же длины.- Норма
|v| = sqrt(2^2 + (-1)^2 + 2^2) = sqrt(9) = 3— это длина вектора, скаляр. v @ vдля двух одномерных массивов — скалярное произведение: 4 + 1 + 4 = 9. Оно равно квадрату длины, это полезная проверка.A @ v: матрица 2×3 переводит вектор из R^3 в R^2. Первая координата: 12 + 0(-1) + 22 = 6, вторая: 02 + 1(-1) + (-1)2 = -3.
Операции и их результаты
Сводная таблица «что с чем можно делать и что получится». Размеры записаны по правилам линейной алгебры, где вектор — столбец n x 1.
| Операция | Условие | Результат |
|---|---|---|
| скаляр * вектор | любой n | вектор той же длины |
| вектор + вектор | одинаковая длина | вектор |
| вектор . вектор (скалярное произведение) | одинаковая длина | скаляр |
| норма вектора | — | скаляр >= 0 |
| матрица m x n * вектор n | число столбцов = длина вектора | вектор длины m |
| матрица m x n * матрица n x k | внутренние размеры совпадают | матрица m x k |
Скалярное произведение связано с углом между векторами: a . b = |a| * |b| * cos(угла). Отсюда правило: если скалярное произведение равно нулю, ненулевые векторы перпендикулярны.
import numpy as np
a = np.array([1.0, 0.0])
b = np.array([1.0, 1.0])
cos_ab = (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b))
angle = np.degrees(np.arccos(np.clip(cos_ab, -1.0, 1.0)))
print(round(float(cos_ab), 4), round(float(angle), 1))
p = np.array([3.0, 4.0])
print(p / np.linalg.norm(p)) # единичный вектор (орт)
Вывод:
0.7071 45.0
[0.6 0.8]
np.clip здесь страховка: из-за округления в числах с плавающей точкой косинус может чуть выйти за [-1, 1], и arccos вернет nan. Деление на норму дает единичный вектор (орт) того же направления. Граница: у нулевого вектора норма 0, и деление дает [nan nan] с предупреждением RuntimeWarning: invalid value encountered in divide — нулевой вектор нормировать нельзя, это надо проверять до деления.
Геометрия векторов подробнее (коллинеарность, сложение по правилу треугольника, координаты) — в статье о векторах и операциях над ними.
Скаляр в NumPy: 0-мерный массив, вектор длины 1 и матрица 1×1
На бумаге 5, (5) и матрица [5] выглядят одинаково. В коде это четыре разных объекта:
import numpy as np
x = np.float64(5.0) # скаляр NumPy
z = np.array(5.0) # 0-мерный массив
one = np.array([5.0]) # вектор длины 1
m = np.full((1, 1), 5.0) # матрица 1x1
for name, obj in [("x", x), ("z", z), ("one", one), ("m", m)]:
print(name, type(obj).__name__, np.shape(obj), np.ndim(obj))
print(z.item(), one[0], m[0, 0]) # достать число как скаляр
print(float(z), type(z.item()).__name__)
Вывод:
x float64 () 0
z ndarray () 0
one ndarray (1,) 1
m ndarray (1, 1) 2
5.0 5.0 5.0
5.0 float
Скалярами в смысле формы являются только x и z (shape ()). Метод .item() возвращает обычное число Python. Разница важна, когда число из массива передается дальше: например, в float().
Неверно — превращать вектор длины 1 в число через float():
import numpy as np
one = np.array([5.0])
print(float(one))
Результат в NumPy 2.5.3:
TypeError: only 0-dimensional arrays can be converted to Python scalars
Исправление — явно взять элемент: float(one[0]) или one.item(). В NumPy с 1.25 по 2.3 такой вызов еще работал с предупреждением DeprecationWarning (проверено на 2.0.2 и 2.3.5), а начиная с 2.4 это ошибка (проверено на 2.4.6 и 2.5.3), поэтому старый код может сломаться только после обновления.
Две частые ошибки с векторами и матрицами
Ошибка 1: * вместо @ для матриц
В NumPy оператор * поэлементный, а матричное произведение — @ (или np.matmul).
import numpy as np
A = np.array([1, 2, 3, 4]).reshape(2, 2) # строки: (1, 2) и (3, 4)
B = np.array([0, 1, 1, 0]).reshape(2, 2) # строки: (0, 1) и (1, 0)
for title, M in [("A * B", A * B), ("A @ B", A @ B), ("A * 10", A * 10)]:
print(title, "->", *M) # печатаем матрицу построчно
Вывод (каждая пара скобок — строка матрицы):
A * B -> [0 2] [3 0]
A @ B -> [2 1] [4 3]
A * 10 -> [10 20] [30 40]
A * B — поэлементное произведение (произведение Адамара), A @ B — матричное.
A * B не ошибка синтаксиса, а другая операция — код молча вернет не то. Для скаляра * корректен: A * 10 умножает каждый элемент. Правило для чтения чужого кода: * со скаляром — растяжение, * между массивами одной формы — поэлементное произведение, @ — произведение из линейной алгебры.
Ошибка 2: несовпадение размеров
Матрицу 2×3 можно умножить только на вектор длины 3:
import numpy as np
A = np.array([1.0, 0.0, 2.0,
0.0, 1.0, -1.0]).reshape(2, 3)
w = np.array([1.0, 2.0])
print(A @ w)
Результат:
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)
Сообщение читается так: у матрицы k = 3 столбца, а у вектора 2 элемента. Исправление — согласовать размеры: вектор длины 3 или транспонированная матрица A.T @ w (3×2 на вектор длины 2 дает вектор длины 3), если по смыслу задачи нужна именно она.
Строка, столбец и почему .T у вектора ничего не делает
Одномерный массив NumPy формы (n,) — это не строка и не столбец, у него одна ось. Поэтому транспонирование его не меняет. Когда ориентация важна, форму задают явно:
import numpy as np
v = np.array([1, 2, 3])
print(v.T.shape) # (3,) - транспонирование 1-D ничего не меняет
col = v.reshape(-1, 1) # явный столбец 3x1
row = v.reshape(1, -1) # явная строка 1x3
print(col.shape, row.shape)
inner = row @ col
print(inner.shape, inner.item()) # матрица 1x1, число берем через item()
outer = col @ row
print(outer.shape, *outer) # внешнее произведение, построчно
Вывод:
(3,)
(3, 1) (1, 3)
(1, 1) 14
(3, 3) [1 2 3] [2 4 6] [3 6 9]
Строка на столбец дает матрицу 1×1 — по числу это скалярное произведение (1 + 4 + 9 = 14), но по форме нет. Столбец на строку дает внешнее произведение: матрицу 3×3. Одни и те же числа, разный порядок множителей — разный результат, потому что умножение матриц в общем случае некоммутативно.
Выводы
- Скаляр — одно число (shape
()), вектор — упорядоченный набор чисел (shape(n,)), матрица — таблица m x n (shape(m, n)); удобно различать их по числу индексов. - Умножение на скаляр возвращает вектор, а скалярное произведение двух векторов возвращает скаляр — это разные операции.
- В NumPy
*поэлементный,@— матричное произведение;A @ wтребует, чтобы число столбцов матрицы совпадало с длиной вектора. - Вектор длины 1 и матрица 1×1 — не скаляры по форме: число из них берется через
.item()или индекс, начиная с NumPy 2.4float()от вектора длины 1 падает сTypeError(до 2.3 включительно — только предупреждение). - Нулевой вектор нельзя нормировать: деление на норму 0 дает
nan.
Где применяется / связь с практикой
Скаляры, векторы и матрицы — базовый словарь анализа данных и машинного обучения. Объект выборки — вектор признаков, таблица данных — матрица, веса линейной модели — вектор, а learning rate — скаляр, на который умножается градиент. Предсказание линейной регрессии для всей выборки — это одно произведение X @ w, и ошибки из разделов выше (форма, * вместо @) — самые частые на первых задачах.
Освойте тему на практике
Если хочется системно пройти линейную алгебру, матанализ и теорию вероятностей с упором на применение в коде, посмотрите курс «Базовая математика для цифровых профессий». Попробовать формат и разобрать отдельные темы можно на бесплатных открытых уроках Otus.
FAQ
Может ли скаляр быть комплексным числом?
Да. Скаляры — элементы поля, над которым задано векторное пространство: в R^n это вещественные числа, в C^n — комплексные. В NumPy для этого есть тип complex128.
Чем np.dot отличается от @?
Для одномерных векторов и двумерных матриц результат совпадает. Различие проявляется на массивах с тремя и более осями: @ трактует их как пакет матриц, а np.dot сворачивает оси по другому правилу, поэтому для линейной алгебры обычно берут @.
Скаляр — это тензор нулевого ранга?
В терминах NumPy и PyTorch — да: тензор с формой () и нулем осей. В дифференциальной геометрии у слова «тензор» более строгое определение, и там скаляр — инвариант, не меняющийся при смене системы координат.



