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 | Объекты boolean в 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 с генератором случайных чисел по умолчанию и начальным значением 42 |
|
| 4 равномерно распределённых образца между 1 и 3 включительно |
|
| два двумерных массива: один с значениями x, другой с значениями y |
| лучший способ вычисления функций на сетке | |
|
| |
| лучший способ вычисления функций на сетке | |
|
| создать m на n копий |
|
| склеить столбцы |
|
| склеить строки |
|
| максимальный элемент |
|
| максимальный элемент каждого столбца массива |
|
| максимальный элемент каждой строки массива |
|
| сравнивает |
|
| норма L2 вектора |
|
| бинарный оператор AND (ufunc NumPy) См. примечание LOGICOPS |
|
| бинарный оператор OR (ufunc NumPy) См. примечание LOGICOPS |
|
| битовый оператор AND (встроенная функция Python и ufunc NumPy) |
|
| битовый оператор OR (родной для Python и NumPy ufunc) |
|
| обратная матрица квадратной 2D-матрицы |
|
| псевдообратная матрица 2D-матрицы |
|
| ранг матрицы 2D-матрицы |
|
| решение уравнения ax = b для x |
| Решить | решение уравнения xa = b для x |
|
| разложение по сингулярным значениям |
|
| факторизация Холецкого 2D-матрицы ( |
|
| собственные значения \(\lambda\) и собственные векторы \(\bar{v}\) |
|
| собственные значения \(\lambda\) и собственные векторы \(\bar{v}\) |
|
| найти |
|
| разложение QR |
|
| разложение LU (примечание: P(MATLAB) == транспонирование(P(NumPy))) |
|
| решение методом сопряжённых градиентов |
|
| преобразование Фурье |
|
| обратное преобразование Фурье |
|
| сортировка каждого столбца 2D-матрицы, |
|
| сортировка каждой строки 2D-матрицы, |
|
| сохранить массив |
|
| выполнить линейную регрессию в виде \(\mathbf{Zx}=\mathbf{y}\) |
|
| уменьшение дискретизации с помощью фильтра низких частот |
|
| вектор уникальных значений в массиве |
|
| удаление одноэлементных измерений массива |
Примечания
Подматрица: Присвоение подматрице может быть выполнено с помощью списков индексов, используя команду 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 — битовые AND/OR, а в MATLAB & и | — логические AND/OR. Они могут казаться одинаковыми, но есть важные различия. Если бы вы использовали операторы MATLAB & или |, вам следует использовать NumPy ufuncs logical_and/logical_or. Заметные различия между операторами MATLAB и NumPy & и |:
- Ввод нелогического типа {0,1}: на выходе NumPy — битовое AND ввода. MATLAB рассматривает любое ненулевое значение как 1 и возвращает логическое AND. Например,
(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 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–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/user/numpy-for-matlab-users.html