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 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 для проверки, равно ли |
|
| комплексные числа |
|
| Верхняя граница относительной погрешности из-за округления в 64-битном формате с плавающей точкой. |
|
| Загрузка переменных 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 |
|
| битовый оператор AND (родной для Python и ufunc NumPy) |
|
| побитовое ИЛИ (Python и NumPy ufunc) |
|
| обратная матрица квадратной 2D-матрицы |
|
| псевдообратная матрица 2D-матрицы |
|
| ранг матрицы 2D-матрицы |
|
| решение уравнения a x = b для x |
| Решить | решение уравнения x a = b для x |
|
| разложение по сингулярным значениям |
|
| разложение Холецкого 2D-матрицы ( |
|
| собственные значения |
|
| собственные значения |
|
| найти |
|
| QR-разложение |
|
| LU-разложение (примечание: P(MATLAB) == transpose(P(NumPy))) |
|
| решение методом сопряжённых градиентов |
|
| преобразование Фурье |
|
| обратное преобразование Фурье |
|
| сортировка каждого столбца 2D-матрицы, |
|
| сортировка каждой строки 2D-матрицы, |
|
| сохранить массив |
|
| линейная регрессия вида |
|
| низкочастотная фильтрация с понижением частоты дискретизации |
|
| вектор уникальных значений в массиве |
|
| удаление одноэлементных размерностей массива |
Примечания
Подматрица: Присвоение подматрицы можно выполнить с помощью списков индексов с использованием команды ix_. Например, для 2D-матрицы a, можно выполнить: ind=[1, 3]; a[np.ix_(ind, ind)] += 100.
Справка: Нет прямого эквивалента команде MATLAB which, но команды help и numpy.source обычно показывают имя файла, где находится функция. Python также имеет модуль inspect (выполните import inspect), который предоставляет getfile инструмент, который часто работает.
ИНДЕКСИРОВАНИЕ: MATLAB использует индексирование, начинающееся с 1, поэтому начальный элемент последовательности имеет индекс 1. Python использует нулевое индексирование, поэтому начальный элемент последовательности имеет индекс 0. Путаница и споры возникают, потому что у каждого есть свои преимущества и недостатки. Индексирование, начинающееся с 1, соответствует общепринятому использованию в естественном языке, где «первый» элемент последовательности имеет индекс 1. Нулевое индексирование упрощает индексирование. См. также текст профессора Эдсгера В. Дейкстры.
ДИАПАЗОНЫ: В MATLAB 0:5 может использоваться как литерал диапазона, так и индекс «среза» (в скобках); однако в Python конструкции, подобные 0:5, только могут использоваться как индекс среза (в квадратных скобках). Таким образом, был создан несколько своеобразный объект r_, чтобы позволить NumPy иметь аналогичный краткий механизм построения диапазонов. Обратите внимание, что r_ не вызывается как функция или конструктор, а индексируется с помощью квадратных скобок, что позволяет использовать синтаксис среза Python в аргументах.
ЛОГИЧЕСКИЕ ОПЕРАЦИИ: & или | в NumPy — это побитовое И/ИЛИ, а в MATLAB & и | — логическое И/ИЛИ. Они могут работать одинаково, но есть важные различия. Если бы вы использовали операторы MATLAB & или |, вы должны использовать NumPy ufuncs logical_and/logical_or. Отличия между операторами MATLAB и NumPy & и |:
- Ввод нелогического типа {0,1}: выход NumPy — это побитовое И ввода. MATLAB рассматривает любое ненулевое значение как 1 и возвращает логическое И. Например,
(3 & 4)в NumPy равно0, а в MATLAB3и4считаются логически истинными, и(3 & 4)возвращает1. - Приоритет: оператор & NumPy имеет более высокий приоритет, чем логические операторы, такие как
<и>; у MATLAB — обратное.
Если вы знаете, что у вас есть булевы аргументы, вы можете обойтись операторами NumPy, но будьте осторожны со скобками, например, так: z
= (x > 1) & (x < 2). Отсутствие операторных форм NumPy logical_and и logical_or — это неудачный результат дизайна Python.
RESHAPE и ЛИНЕЙНОЕ ИНДЕКСИРОВАНИЕ: MATLAB всегда позволяет обращаться к многомерным массивам с помощью скалярных или линейных индексов, NumPy — нет. Линейные индексы распространены в программах MATLAB, например, find() для матрицы возвращают их, в то время как NumPy find ведет себя по-другому. При преобразовании кода MATLAB может потребоваться предварительно преобразовать матрицу в линейную последовательность, выполнить операции индексирования, а затем вернуть исходную форму. Поскольку reshape (обычно) создаёт представления той же памяти, это должно быть достаточно эффективным. Обратите внимание, что порядок обхода, используемый reshape в NumPy, по умолчанию соответствует порядку «C», в то время как MATLAB использует порядок Fortran. Если вы просто преобразуете в линейную последовательность и обратно, это не имеет значения. Но если вы преобразуете reshape из кода MATLAB, который зависит от порядка обхода, то этот код MATLAB: z =
reshape(x,3,4); должен стать z = x.reshape(3,4,order='F').copy() в NumPy.
Массив или матрица? Что использовать?
Исторически 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–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/user/numpy-for-matlab-users.html