NumPy для пользователей MATLAB#
Введение#
MATLAB® и NumPy имеют много общего, но NumPy был создан для работы с Python, а не как клон MATLAB. Это руководство поможет пользователям MATLAB начать работу с NumPy.
Некоторые ключевые различия#
В MATLAB базовый тип, даже для скаляров, является многомерным массивом. Присваивания массивов в MATLAB хранятся как 2D массивы чисел с плавающей точкой двойной точности, если вы не укажете количество измерений и тип. Операции над 2D экземплярами этих массивов моделируются на основе матричных операций в линейной алгебре. |
В 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 |
Примечания |
|---|---|---|
|
|
получить справку по функции функция |
|
выяснить, где функция определен |
|
|
|
вывести исходный код для функция (если не нативная функция) |
|
|
закомментируйте строку кода текстом |
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
|
The логические объекты
в 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-го измерения массива |
|
|
определить 2D массив 2x3 |
|
|
построить матрицу из блоков |
|
|
доступ к последнему элементу в векторе MATLAB (1xn или nx1) или 1D массиве NumPy
|
|
|
доступ к элементу во второй строке, пятом столбце в 2D массиве |
|
|
вся вторая строка 2D массива |
|
|
первые 5 строк 2D массива |
|
|
последние 5 строк двумерного массива |
|
|
Первая-третья строки и пятый-девятый столбцы двумерного массива, |
|
|
строки 2,4 и 5 и столбцы 1 и 3. Это позволяет изменять матрицу и не требует регулярного среза. |
|
|
каждая вторая строка |
|
|
каждая вторая строка |
|
|
|
|
|
|
|
|
транспонирование |
|
|
сопряжённая транспонированная матрица |
|
|
matrix multiply |
|
|
поэлементное умножение |
|
|
поэлементное деление |
|
|
поэлементное возведение в степень |
|
|
матрица, чей i,j-й элемент (a_ij > 0.5). Результат MATLAB — массив логических значений 0 и 1. Результат NumPy — массив булевых значений |
|
|
найти индексы, где ( |
|
|
извлечь столбцы |
|
|
извлечь столбцы |
|
|
|
|
|
|
|
|
установить все значения в одно и то же скалярное значение |
|
|
NumPy присваивает по ссылке |
|
|
Срезы NumPy передаются по ссылке |
|
|
преобразовать массив в вектор (обратите внимание, что это приводит к копированию). Чтобы получить
тот же порядок данных, что и в MATLAB, используйте |
|
|
создать возрастающий вектор (см. примечание ДИАПАЗОНЫ) |
|
|
создать возрастающий вектор (см. примечание ДИАПАЗОНЫ) |
|
|
создать вектор-столбец |
|
|
3x4 двумерный массив, полностью состоящий из 64-битных чисел с плавающей запятой нулей |
|
|
трёхмерный массив 3x4x5, полностью заполненный нулями с плавающей точкой двойной точности |
|
|
3x4 двумерный массив, полностью заполненный единицами с плавающей точкой 64-бит |
|
|
единичная матрица 3x3 |
|
|
возвращает вектор диагональных элементов 2D массива, |
|
|
возвращает квадратную диагональную матрицу, ненулевые значения которой — элементы
вектора, |
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 включительно |
|
|
два 2D массива: один со значениями x, другой со значениями y |
|
лучший способ вычисления функций на сетке |
|
|
|
|
|
лучший способ вычисления функций на сетке |
|
|
|
создать m на n копий |
|
|
объединить столбцы |
|
|
объединить строки |
|
|
максимальный элемент |
|
|
максимальный элемент каждого столбца массива |
|
|
максимальный элемент каждой строки массива |
|
|
сравнивает |
|
|
Норма L2 вектора |
|
|
поэлементный оператор AND (NumPy ufunc) См. примечание LOGICOPS |
|
|
поэлементный оператор OR (NumPy ufunc) См. примечание LOGICOPS |
|
|
побитовый оператор AND (нативный Python и ufunc NumPy) |
|
|
побитовый оператор ИЛИ (нативный Python и ufunc NumPy) |
|
|
обратная матрица квадратного 2D массива |
|
|
псевдообратная матрица 2D массива |
|
|
ранг матрицы 2D массива |
|
|
решение a x = b для x |
|
Решить |
решение x a = b для x |
|
|
сингулярное разложение |
|
|
Разложение Холецкого двумерного массива |
|
|
собственные значения \(\lambda\) и собственные векторы \(v\) of |
|
|
собственные значения \(\lambda\) и собственные векторы \(v\) of
|
|
|
найти |
|
|
QR-разложение |
|
|
LU-разложение с частичным выбором ведущего элемента (примечание: P(MATLAB) == transpose(P(NumPy))) |
|
|
решатель сопряжённых градиентов |
|
|
Преобразование Фурье от |
|
|
обратное преобразование Фурье |
|
|
отсортировать каждый столбец двумерного массива, |
|
|
сортировать каждую строку 2D массива, |
|
|
сохранить массив |
|
|
выполнить линейную регрессию вида \(\mathbf{Zx}=\mathbf{y}\) |
|
|
понижение частоты дискретизации с фильтрацией нижних частот |
|
|
вектор уникальных значений в массиве |
|
|
удалить одноэлементные размерности массива |
Примечания#
Подматрица: Присваивание подматрице может быть выполнено с помощью списков
индексов, используя ix_ команда. Например, для 2D массива a, можно сделать: ind=[1, 3]; a[np.ix_(ind, ind)] += 100.
ПОМОЩЬ: Нет прямого эквивалента MATLAB which команда, но команды help обычно указывает имя файла,
где находится функция. Python также имеет inspect модуль (do
import inspect), который предоставляет getfile что часто работает.
ИНДЕКСАЦИЯ: MATLAB использует индексацию с единицы, поэтому начальный элемент последовательности имеет индекс 1. Python использует индексацию с нуля, поэтому начальный элемент последовательности имеет индекс 0. Путаница и споры возникают потому что у каждого подхода есть преимущества и недостатки. Индексация с единицы согласуется с обычным использованием в человеческом языке, где «первый» элемент последовательности имеет индекс 1. Индексация с нуля упрощает индексацию. См. также текст проф. др. Эдсгера В. Дейкстры.
ДИАПАЗОНЫ: В MATLAB, 0:5 может использоваться как как литерал диапазона, так и как индекс 'среза' (внутри скобок); однако в Python конструкции, такие как 0:5 может only может использоваться как индекс среза (внутри квадратных скобок). Отсюда несколько необычный r_ объект был создан, чтобы позволить
NumPy иметь аналогичный краткий механизм построения диапазонов. Обратите внимание, что
r_ не вызывается как функция или конструктор, а скорее
индексированный используя квадратные скобки, что позволяет использовать синтаксис срезов
Python в аргументах.
LOGICOPS: & или | в NumPy побитовое И/ИЛИ, тогда как в MATLAB &
и | являются логическими И/ИЛИ. Оба могут казаться работающими одинаково, но есть важные различия. Если бы вы использовали MATLAB's &
или | операторы, вы должны использовать универсальные функции NumPy
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() на матрице возвращает их, тогда как find в NumPy ведет себя иначе. При преобразовании кода MATLAB может потребоваться сначала преобразовать матрицу в линейную последовательность, выполнить некоторые операции индексирования, а затем преобразовать обратно. Поскольку reshape (обычно) создает представления одного и того же хранилища, это должно быть достаточно эффективно. Обратите внимание, что порядок сканирования, используемый reshape в NumPy, по умолчанию является порядком 'C', тогда как MATLAB использует порядок Fortran. Если вы просто преобразуете в линейную последовательность и обратно, это не имеет значения. Но если вы преобразуете reshape из кода 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 класс. The
array класс предназначен для использования в качестве универсального n-мерного массива для многих видов численных вычислений, в то время как matrix предназначен для
облегчения вычислений линейной алгебры в частности. На практике существует
лишь несколько ключевых различий между ними.
Операторы
*и@, функцииdot(), иmultiply():Для
array,*означает поэлементное умножение, в то время как@означает умножение матриц; у них есть связанные функцииmultiply()и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()матрицы, соответственно.
Удобный конструктор
The
arrayконструктор принимает (вложенные) последовательности Python в качестве инициализаторов. Как в,array([[1,2,3],[4,5,6]]).The
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немного чище.
The 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
Чтобы использовать устаревший матрица и другие 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 можно найти на https://mathesaurus.sf.net/
Обширный список инструментов для научной работы с Python можно найти в тематическая страница программного обеспечения.
См. Список программного обеспечения Python: скриптовые языки для списка программного обеспечения, использующего Python в качестве языка сценариев
MATLAB® и SimuLink® являются зарегистрированными товарными знаками The MathWorks, Inc.