NumPy для пользователей MATLAB
Введение
MATLAB® и NumPy имеют много общего, но NumPy был создан для работы с Python, а не для того, чтобы быть клоном MATLAB. Это руководство поможет пользователям MATLAB начать работу с NumPy.
Основные отличия
В MATLAB базовый тип, даже для скаляров, является многомерным массивом. Присваивания массивов в MATLAB хранятся как двумерные массивы с плавающей точкой двойной точности, если вы не укажете количество измерений и тип. Операции над двумерными экземплярами этих массивов моделируются на операциях с матрицами в линейной алгебре. | В NumPy базовый тип является многомерным |
В MATLAB индексы нумеруются с 1; | NumPy, как и Python, нумерует индексы с 0; |
Язык сценариев MATLAB был создан для линейной алгебры, поэтому синтаксис некоторых манипуляций с массивами более компактен, чем в NumPy. С другой стороны, API для добавления графических интерфейсов пользователя и создания полноценных приложений является, так сказать, вторичным. | NumPy основан на Python, универсальном языке программирования. Преимущество NumPy заключается в доступе к библиотекам Python, включая: SciPy, Matplotlib, Pandas, OpenCV и многое другое. Кроме того, Python часто встраивается в качестве языка сценариев в другие программы, что позволяет использовать NumPy и там. |
Фрагментация массивов MATLAB использует семантику передачи по значению, с ленивой схемой копирования при записи, чтобы предотвратить создание копий до тех пор, пока они не понадобятся. Операции фрагментации копируют части массива. | Фрагментация массивов NumPy использует передачу по ссылке, которая не копирует аргументы. Операции фрагментации являются представлениями в массиве. |
Приблизительные эквиваленты
В таблице ниже приведены приблизительные эквиваленты некоторых распространенных выражений MATLAB. Это подобные выражения, а не эквиваленты. Подробности см. в документации.
В таблице ниже предполагается, что вы выполнили следующие команды в Python:
import numpy as np from scipy import io, integrate, linalg, signal from scipy.sparse.linalg import cg, eigs
Также предполагается, что, если в примечаниях говорится о «матрице», то аргументы являются двумерными сущностями.
Общие эквиваленты
MATLAB | NumPy | Примечания |
|---|---|---|
|
| получить справку по функции func |
| узнать, где определена func | |
|
| вывести исходный код для func (если это не встроенная функция) |
|
| комментировать строку кода текстом |
for i=1:3
fprintf('%i\n',i)
end
|
for i in range(1, 4): print(i) | использовать цикл for для печати чисел 1, 2 и 3 с использованием |
|
| оператор логического И с короткой цепочкой вычислений (встроенный оператор Python); только скалярные аргументы |
|
| оператор логического ИЛИ с короткой цепочкой вычислений (встроенный оператор Python); только скалярные аргументы |
>> 4 == 4 ans = 1 >> 4 == 5 ans = 0 |
>>> 4 == 4 True >>> 4 == 5 False | Объекты булевых типов в Python равны |
a=4
if a==4
fprintf('a = 4\n')
elseif a==5
fprintf('a = 5\n')
end
|
a = 4
if a == 4:
print('a = 4')
elif a == 5:
print('a = 5')
| создать оператор if-else для проверки, равен ли |
|
| комплексные числа |
|
| расстояние от 1 до ближайшего большего представимого действительного числа в формате двойной точности |
|
| Загрузить переменные MATLAB, сохраненные в файле |
|
| интегрировать обыкновенное дифференциальное уравнение с помощью метода Рунге-Кутта 4,5 |
|
| интегрировать обыкновенное дифференциальное уравнение с помощью метода BDF |
Эквиваленты линейной алгебры
MATLAB | NumPy | Примечания |
|---|---|---|
|
| количество измерений массива |
|
| количество элементов массива |
|
| «размер» массива |
|
| получить количество элементов n-го измерения массива |
|
| определить двумерный массив 2x3 |
|
| построить матрицу из блоков |
|
| доступ к последнему элементу в векторе MATLAB (1xn или nx1) или одномерном массиве NumPy |
|
| доступ к элементу во второй строке, пятом столбце двумерного массива |
|
| вся вторая строка двумерного массива |
|
| первые 5 строк двумерного массива |
|
| последние 5 строк двумерного массива |
|
| Первые три строки и пятый по девятый столбцы двумерного массива, |
|
| строки 2, 4 и 5 и столбцы 1 и 3. Это позволяет изменять матрицу и не требует обычного среза. |
|
| каждая вторая строка |
|
| каждая вторая строка |
|
|
|
|
|
|
|
| транспонирование |
|
| сопряженное транспонирование |
|
| умножение матриц |
|
| умножение по элементам |
|
| деление по элементам |
|
| возведение в степень по элементам |
|
| матрица, i,j-й элемент которой равен (a_ij > 0.5). Результат MATLAB — массив логических значений 0 и 1. Результат NumPy — массив булевых значений |
|
| найти индексы, где ( |
|
| извлечь столбцы |
|
| извлечь столбцы |
|
|
|
|
|
|
|
| установить все значения на одно скалярное значение |
|
| NumPy присваивает по ссылке |
|
| Срезы NumPy по ссылке |
|
| преобразовать массив в вектор (обратите внимание, что это принудительно создаёт копию). Чтобы получить такой же порядок данных, как в MATLAB, используйте |
|
| создание возрастающего вектора (см. примечание ДИАПАЗОНЫ) |
|
| создание возрастающего вектора (см. примечание ДИАПАЗОНЫ) |
|
| создание столбца-вектора |
|
| двумерный массив 3x4, заполненный нулями с плавающей точкой двойной точности (64 бита) |
|
| трёхмерный массив 3x4x5, заполненный нулями с плавающей точкой двойной точности (64 бита) |
|
| двумерный массив 3x4, заполненный единицами с плавающей точкой двойной точности (64 бита) |
|
| единичная матрица 3x3 |
|
| возвращает вектор диагональных элементов двумерного массива, |
|
| возвращает квадратную диагональную матрицу, ненулевые значения которой — элементы вектора, |
rng(42,'twister') rand(3,4) |
from numpy.random import default_rng rng = default_rng(42) rng.random(3, 4) или более старая версия: | сгенерировать случайный массив 3x4 с генератором случайных чисел по умолчанию и seed = 42 |
|
| 4 равномерно распределённых образца между 1 и 3 включительно |
|
| два двумерных массива: один с x-значениями, другой с y-значениями |
| наиболее эффективный способ вычисления функций на сетке | |
|
| |
| наиболее эффективный способ вычисления функций на сетке | |
|
| создать m на n копий |
|
| склеить столбцы |
|
| склеить строки |
|
| максимальный элемент |
|
| максимальный элемент каждого столбца массива |
|
| максимальный элемент каждой строки массива |
|
| сравнивает |
|
| норма L2 вектора |
|
| поэлементный оператор AND (ufunc NumPy) См. примечание LOGICOPS |
|
| поэлементный оператор OR (ufunc NumPy) См. примечание LOGICOPS |
|
| оператор поразрядного И (встроенный в Python и ufunc NumPy) |
|
| оператор поразрядного ИЛИ (встроенный в Python и ufunc NumPy) |
|
| обратная матрица квадратной 2D матрицы |
|
| псевдообратная 2D матрица |
|
| ранг матрицы 2D массива |
|
| решение уравнения a x = b для x |
| Решить | решение уравнения x a = b для x |
|
| разложение по сингулярным значениям |
|
| разложение Холецкого 2D массива |
|
| собственные значения \(\lambda\) и собственные векторы \(v\) |
|
| собственные значения \(\lambda\) и собственные векторы \(v\) |
|
| найти |
|
| QR-разложение |
|
| LU-разложение с частичным выбором ведущего элемента (примечание: P(MATLAB) == transpose(P(NumPy))) |
|
| решение методом сопряжённых градиентов |
|
| преобразование Фурье |
|
| обратное преобразование Фурье |
|
| сортировка каждой колонки 2D массива, |
|
| сортировка каждой строки 2D массива, |
|
| сохранить массив |
|
| выполнить линейную регрессию вида \(\mathbf{Zx}=\mathbf{y}\) |
|
| децимация с применением фильтра нижних частот |
|
| вектор уникальных значений в массиве |
|
| удаление одноэлементных размерностей массива |
Примечания
Подматрица: Присвоение подматрицы может быть выполнено с использованием списков индексов с помощью команды ix_. Например, для 2D массива a, можно сделать так: ind=[1, 3]; a[np.ix_(ind, ind)] += 100.
Справка: Нет прямого эквивалента команды MATLAB which, но команды help обычно отображают имя файла, в котором находится функция. Python также имеет модуль inspect (выполните import inspect), который предоставляет инструмент getfile часто работающий.
ИНДЕКСИРОВАНИЕ: MATLAB использует индексирование с единицы, поэтому начальный элемент последовательности имеет индекс 1. Python использует нулевое индексирование, поэтому начальный элемент последовательности имеет индекс 0. Путаница и споры возникают из-за того, что у каждого есть свои плюсы и минусы. Индексирование с единицы соответствует обычному использованию человеческой речи, где «первый» элемент последовательности имеет индекс 1. Нулевое индексирование упрощает индексирование. См. также текст профессора Эдсгера В. Дейкстры.
ДИАПАЗОНЫ: В MATLAB, 0:5 может использоваться как литерал диапазона, так и индекс «срезов» (в скобках); однако в Python конструкции вроде 0:5 только могут использоваться как индексы срезов (в квадратных скобках). Поэтому был создан несколько необычный объект r_, чтобы позволить NumPy иметь аналогичный лаконичный механизм построения диапазонов. Обратите внимание, что r_ не вызывается как функция или конструктор, а индексируется с использованием квадратных скобок, что позволяет использовать синтаксис срезов Python в аргументах.
ЛОГИЧЕСКИЕ ОПЕРАТОРЫ: & или | в NumPy — поразрядные И/ИЛИ, в то время как в MATLAB & и | — логическое И/ИЛИ. Они могут работать одинаково, но есть важные различия. Если вы использовали бы операторы MATLAB & или |, то вам следует использовать NumPy ufunc logical_and/logical_or. Отличия между операторами MATLAB & и | NumPy:
- Ввод нелогического типа {0,1}: вывод NumPy — поразрядное И входных данных. MATLAB рассматривает любое ненулевое значение как 1 и возвращает логическое И. Например,
(3 & 4)в NumPy —0, в то время как в MATLAB и3и4считаются логически истинными и(3 & 4)возвращает1. - Приоритет: оператор & NumPy имеет больший приоритет, чем логические операторы, такие как
<и>, в MATLAB — наоборот.
Если вы знаете, что у вас есть булевы аргументы, вы можете обойтись операторами NumPy, но будьте внимательны с круглыми скобками, например, так: z
= (x > 1) & (x < 2). Отсутствие операторных форм NumPy logical_and и logical_or — следствие дизайна Python.
RESHAPE и ЛИНЕЙНОЕ ИНДЕКСИРОВАНИЕ: MATLAB всегда позволяет многомерным массивам быть доступными с использованием скалярных или линейных индексов, NumPy — нет. Линейные индексы часто встречаются в программах MATLAB, например, find() на матрице возвращает их, в то время как NumPy’s find ведет себя иначе. При конвертации кода MATLAB может потребоваться сначала преобразовать матрицу в линейную последовательность, выполнить операции индексирования, а затем преобразовать обратно. Поскольку reshape (обычно) создаёт представления по одному хранилищу, это должно быть выполнено достаточно эффективно. Обратите внимание, что порядок сканирования, используемый reshape в NumPy, по умолчанию — ‘C’ порядок, в то время как MATLAB использует порядок Fortran. Если вы просто преобразуете в линейную последовательность и обратно, это не имеет значения. Но если вы преобразуете перестановки из кода MATLAB, который полагается на порядок сканирования, то этот код MATLAB: z =
reshape(x,3,4); должен стать z = x.reshape(3,4,order='F').copy() в NumPy.
‘array’ или ‘matrix’? Какой тип использовать?
Исторически NumPy предоставлял специальный тип матриц, np.matrix, который является подклассом ndarray и делает бинарные операции операциями линейной алгебры. Вы можете видеть его использование в некоторых существующих кодах вместо np.array. Так какой тип использовать?
Краткий ответ
Используйте массивы.
- Они поддерживают многомерную алгебру массивов, которая поддерживается в MATLAB
- Они являются стандартным типом векторов/матриц/тензоров в NumPy. Многие функции NumPy возвращают массивы, а не матрицы.
- Существует чёткое различие между поэлементными операциями и операциями линейной алгебры.
- Вы можете иметь стандартные векторы или векторы строки/столбца, если хотите.
До Python 3.5 единственным недостатком использования типа массива было то, что вам приходилось использовать dot вместо * для умножения (сведения) двух тензоров (скалярное произведение, умножение матрицы на вектор и т. д.). С Python 3.5 вы можете использовать оператор умножения матриц @.
Учитывая вышесказанное, мы намерены в конечном итоге устареть matrix.
Подробный ответ
NumPy содержит как класс array, так и класс matrix. Класс array предназначен для использования в качестве многомерного массива общего назначения для различных видов численных вычислений, в то время как matrix предназначен для упрощения вычислений линейной алгебры. На практике между ними есть лишь несколько ключевых отличий.
-
Операторы
*и@, функцииdot(), иmultiply().- Для
array, ``*`` означает поэлементное умножение, а ``@`` означает умножение матриц; они имеют связанные функцииmultiply()иdot(). (До Python 3.5@не существовало, и для умножения матриц нужно было использоватьdot()). - Для
matrix, ``*`` означает умножение матриц, а для поэлементного умножения нужно использовать функциюmultiply().
- Для
-
Обработка векторов (одномерные массивы)
- Для
array, формы векторов 1xN, Nx1 и N - это разные вещи. Такие операции, какA[:,1], возвращают одномерный массив формы N, а не двумерный массив формы Nx1. Транспонирование одномерногоarrayничего не делает. - Для
matrix, одномерные массивы всегда повышаются до 1xN или Nx1 матриц (векторов строки или столбца).A[:,1]возвращает двумерную матрицу формы Nx1.
- Для
-
Обработка многомерных массивов (ndim > 2)
-
arrayобъекты могут иметь количество измерений > 2; -
matrixобъекты всегда имеют ровно два измерения.
-
-
Удобные атрибуты
-
arrayимеет атрибут .T, который возвращает транспонированное данные. -
matrixтакже имеет атрибуты .H, .I и .A, которые возвращают сопряжённо-транспонированную, обратную иasarray()матрицы соответственно.
-
-
Удобный конструктор
- Конструктор
arrayпринимает (вложенные) Python последовательности в качестве инициализаторов. Как вarray([[1,2,3],[4,5,6]]). - Конструктор
matrixдополнительно принимает удобную строковую инициализацию. Как вmatrix("[1 2 3; 4 5 6]").
- Конструктор
Использование обоих типов имеет свои преимущества и недостатки:
-
array-
:)Поэлементное умножение легко выполняется:A*B. -
:(Вам нужно помнить, что умножение матриц имеет свой оператор@. -
:)Вы можете рассматривать одномерные массивы как либо векторы строки, либо векторы столбца.A @ vрассматриваетvкак вектор столбца, аv @ Aрассматриваетvкак вектор строки. Это может сэкономить вам много написания транспонирования. -
:)arrayявляется "стандартным" типом NumPy, поэтому он проходит наибольшее тестирование и является типом, который чаще всего возвращают сторонние библиотеки, использующие NumPy. -
:)Хорошо справляется с обработкой данных любого количества измерений. -
:)Ближе к семантике алгебры тензоров, если вы с ней знакомы. -
:)Все операции (*,/,+,-и т. д.) являются поэлементными. -
:(Разреженные матрицы изscipy.sparseне взаимодействуют так хорошо с массивами.
-
-
matrix-
:\\Поведение более похоже на поведение матриц в MATLAB. -
<:(Максимально двумерный. Для хранения трехмерных данных вам нуженarrayили, возможно, Python списокmatrix. -
<:(Минимально двумерный. У вас не может быть векторов. Они должны быть преобразованы в матрицы с одним столбцом или одной строкой. -
<:(Посколькуarrayявляется стандартным в NumPy, некоторые функции могут возвращатьarrayдаже если вы передаете имmatrixв качестве аргумента. Это не должно происходить с функциями NumPy (если это происходит, это ошибка), но сторонние библиотеки, основанные на NumPy, могут не сохранять тип данных, как это делает NumPy. -
:)A*Bпредставляет умножение матриц, поэтому выглядит так же, как вы это записываете в линейной алгебре (для Python ≥ 3.5 обычные массивы имеют ту же удобство с оператором@). -
<:(Поэлементное умножение требует вызова функцииmultiply(A,B). -
<:(Использование перегрузки операторов немного нелогично:*не работает поэлементно, но/работает. - Взаимодействие с
scipy.sparseнемного чище.
-
Таким образом, использование array гораздо предпочтительнее. Действительно, мы намерены в конечном итоге устареть matrix.
Настройка вашей среды
В MATLAB основным инструментом для настройки среды является изменение пути поиска с местоположениями ваших любимых функций. Вы можете поместить такие настройки в скрипт запуска, который MATLAB будет запускать при запуске.
NumPy, или скорее Python, имеют аналогичные возможности.
- Чтобы изменить путь поиска Python, включив расположения собственных модулей, определите переменную среды
PYTHONPATH. - Чтобы запустить определенный скрипт при запуске интерактивного интерпретатора Python, определите переменную среды
PYTHONSTARTUPдля содержанием имени вашего скрипта запуска.
В отличие от MATLAB, где всё в вашем пути можно вызвать сразу, в Python вам сначала необходимо выполнить оператор «import», чтобы сделать функции в конкретном файле доступными.
Например, вы можете создать скрипт запуска, который выглядит так (Примечание: это просто пример, а не «лучшие практики»):
# Make all numpy available via shorter 'np' prefix
import numpy as np
#
# Make the SciPy linear algebra functions available as linalg.func()
# e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution)
from scipy import linalg
#
# Define a Hermitian function
def hermitian(A, **kwargs):
return np.conj(A,**kwargs).T
# Make a shortcut for hermitian:
# hermitian(A) --> H(A)
H = hermitian
Чтобы использовать устаревшие matrix и другие matlib функции:
# Make all matlib functions accessible at the top level via M.func() import numpy.matlib as M # Make some matlib functions accessible directly at the top level via, e.g. rand(3,3) from numpy.matlib import matrix,rand,zeros,ones,empty,eye
Ссылки
Другая несколько устаревшая ссылка MATLAB/NumPy можно найти по адресу http://mathesaurus.sf.net/
Полный список инструментов для научных работ с Python можно найти на странице специализированного программного обеспечения.
См. Список программного обеспечения Python: скрипты, чтобы узнать список программного обеспечения, которое использует Python как язык сценариев
MATLAB® и SimuLink® являются зарегистрированными товарными знаками компании The MathWorks, Inc.
© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/user/numpy-for-matlab-users.html