Spec-Zone.ru › NumPy 1.18

NumPy для пользователей Matlab

Введение

MATLAB® и NumPy/SciPy имеют много общего. Но есть и много различий. NumPy и SciPy были созданы для наиболее естественной работы с численными и научными вычислениями на Python, а не для того, чтобы быть клонами MATLAB®. Эта страница предназначена для сбора информации о различиях, в основном для помощи опытным пользователям MATLAB® в освоении NumPy и SciPy.

Основные отличия

В MATLAB® базовый тип данных — многомерный массив с плавающей точкой двойной точности. Большинство выражений принимают такие массивы и возвращают такие массивы. Операции над двумерными экземплярами этих массивов разработаны так, чтобы действовать более или менее как матричные операции в линейной алгебре.

В NumPy базовый тип — многомерный array. Операции над этими массивами во всех размерностях, включая 2D, являются поэлементными операциями. Для операций линейной алгебры необходимо использовать специальные функции (хотя для умножения матриц можно использовать оператор @ в Python 3.5 и выше).

MATLAB® использует индексирование с 1 (один). Начальный элемент последовательности находится с помощью a(1). См. примечание ИНДЕКСИРОВАНИЕ

Python использует индексирование с 0 (ноль). Начальный элемент последовательности находится с помощью a[0].

Язык сценариев MATLAB® был создан для выполнения операций линейной алгебры. Синтаксис для основных матричных операций удобен и понятен, но API для добавления графических интерфейсов и создания полноценных приложений — это скорее дополнение.

NumPy базируется на Python, который изначально был разработан как превосходный универсальный язык программирования. Хотя синтаксис Matlab для некоторых манипуляций с массивами более компактен, чем синтаксис NumPy, NumPy (как расширение Python) может выполнять многие вещи, которые Matlab просто не может, например, правильно обрабатывать стеки матриц.

В MATLAB® массивы имеют семантику передачи по значению, со схемой ленивой копии-при записи, чтобы предотвратить фактическое создание копий до тех пор, пока они не понадобятся. Операции срезов копируют части массива.

В NumPy массивы имеют семантику передачи по ссылке. Операции срезов представляют собой представления в массиве.

«Массив» или «матрица»? Какой из них использовать?

Исторически NumPy предоставлял специальный тип матрицы, np.matrix, который является подклассом ndarray, делающим бинарные операции операциями линейной алгебры. Вы можете увидеть его в некоторых существующих кодах вместо np.array. Так какой же из них использовать?

Кратко

Используйте массивы.

  • Они являются стандартным типом векторов/матриц/тензоров 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-NumPy

Таблица ниже предоставляет приблизительные эквиваленты для некоторых распространённых выражений MATLAB®. Это не точные эквиваленты, а скорее подсказки для того, чтобы вы двигались в правильном направлении. Более подробную информацию см. в встроенной документации функций NumPy.

В таблице ниже предполагается, что вы выполнили следующие команды в Python:

from numpy import *
import scipy.linalg

Также предполагается ниже, что если в Примечаниях говорится о «матрице», то аргументы являются двумерными сущностями.

Эквиваленты общего назначения

MATLAB

numpy

Примечания

help func

info(func) или help(func) или func? (в Ipython)

получить справку по функции func

which func

см. примечание HELP

узнать, где определена функция func

type func

source(func) или func?? (в Ipython)

вывести исходный код функции func (если это не встроенная функция)

a && b

a and b

короткое логическое И (унарный оператор Python); только скалярные аргументы

a || b

a or b

короткое логическое ИЛИ (унарный оператор Python); только скалярные аргументы

1*i, 1*j, 1i, 1j

1j

комплексные числа

eps

np.spacing(1)

Расстояние между 1 и ближайшим числом с плавающей точкой.

ode45

scipy.integrate.solve_ivp(f)

интегрирование ОДУ методом Рунге-Кутты 4,5

ode15s

scipy.integrate.solve_ivp(f, method='BDF')

интегрирование ОДУ методом BDF

Эквиваленты линейной алгебры

MATLAB

NumPy

Примечания

ndims(a)

ndim(a) или a.ndim

получить число измерений массива

numel(a)

size(a) или a.size

получить число элементов массива

size(a)

shape(a) или a.shape

получить «размер» матрицы

size(a,n)

a.shape[n-1]

получить число элементов n-го измерения массива a. (Обратите внимание, что MATLAB® использует индексацию с 1, а Python — с 0. См. примечание ИНДЕКСИРОВАНИЕ)

[ 1 2 3; 4 5 6 ]

array([[1.,2.,3.], [4.,5.,6.]])

матричная константа 2x3

[ a b; c d ]

block([[a,b], [c,d]])

создание матрицы из блоков a, b, c, и d

a(end)

a[-1]

доступ к последнему элементу в матрице 1xn a

a(2,5)

a[1,4]

доступ к элементу во второй строке, пятом столбце

a(2,:)

a[1] или a[1,:]

вся вторая строка a

a(1:5,:)

a[0:5] или a[:5] или a[0:5,:]

первые пять строк a

a(end-4:end,:)

a[-5:]

последние пять строк a

a(1:3,5:9)

a[0:3][:,4:9]

строки с первой по третью и столбцы с пятым по девятый из a. Это предоставляет чтение только для чтения.

a([2,4,5],[1,3])

a[ix_([1,3,4],[0,2])]

строки 2, 4 и 5 и столбцы 1 и 3. Это позволяет изменять матрицу и не требует обычного среза.

a(3:2:21,:)

a[ 2:21:2,:]

каждая вторая строка a, начиная с третьей и заканчивая двадцать первой

a(1:2:end,:)

a[ ::2,:]

каждая вторая строка a, начиная с первой

a(end:-1:1,:) или flipud(a)

a[ ::-1,:]

a со строками в обратном порядке

a([1:end 1],:)

a[r_[:len(a),0]]

a с копией первой строки, добавленной в конец

a.'

a.transpose() или a.T

транспонирование a

a'

a.conj().transpose() или a.conj().T

сопряженное транспонирование a

a * b

a @ b

умножение матриц

a .* b

a * b

элементное умножение

a./b

a/b

элементное деление

a.^3

a**3

элементная экспоненциация

(a>0.5)

(a>0.5)

матрица, i,j-й элемент которой равен (a_ij > 0,5). Результат Matlab — массив из 0 и 1. Результат NumPy — массив с логическими значениями False и True.

find(a>0.5)

nonzero(a>0.5)

найти индексы, где (a > 0,5)

a(:,find(v>0.5))

a[:,nonzero(v>0.5)[0]]

извлечь столбцы a где вектор v > 0,5

a(:,find(v>0.5))

a[:,v.T>0.5]

извлечь столбцы a где столбец-вектор v > 0,5

a(a<0.5)=0

a[a<0.5]=0

a с элементами, меньшими 0,5, обнуленными

a .* (a>0.5)

a * (a>0.5)

a с элементами, меньшими 0,5, обнуленными

a(:) = 3

a[:] = 3

установить все значения на одно скалярное значение

y=x

y = x.copy()

NumPy присваивает по ссылке

y=x(2,:)

y = x[1,:].copy()

слайсы NumPy — по ссылке

y=x(:)

y = x.flatten()

преобразование массива в вектор (обратите внимание, что это принудительно создает копию)

1:10

arange(1.,11.) или r_[1.:11.] или r_[1:10:10j]

создание возрастающего вектора (см. примечание ДИАПАЗОНЫ)

0:9

arange(10.) или r_[:10.] или r_[:9:10j]

создание возрастающего вектора (см. примечание ДИАПАЗОНЫ)

[1:10]'

arange(1.,11.)[:, newaxis]

создание столбца-вектора

zeros(3,4)

zeros((3,4))

двумерный массив 3x4, заполненный 64-битными числами с плавающей запятой, равными нулю

zeros(3,4,5)

zeros((3,4,5))

трехмерный массив 3x4x5, заполненный 64-битными числами с плавающей запятой, равными нулю

ones(3,4)

ones((3,4))

двумерный массив 3x4, заполненный 64-битными числами с плавающей запятой, равными единице

eye(3)

eye(3)

единичная матрица 3x3

diag(a)

diag(a)

вектор диагональных элементов a

diag(a,0)

diag(a,0)

квадратная диагональная матрица, ненулевые значения которой — элементы a

rand(3,4)

random.rand(3,4) или random.random_sample((3, 4))

случайная матрица 3x4

linspace(1,3,4)

linspace(1,3,4)

4 равномерно распределённых образца между 1 и 3 включительно

[x,y]=meshgrid(0:8,0:5)

mgrid[0:9.,0:6.] или meshgrid(r_[0:9.],r_[0:6.]

два двумерных массива: один из значений x, другой из значений y

ogrid[0:9.,0:6.] или ix_(r_[0:9.],r_[0:6.]

лучший способ вычисления функций на сетке

[x,y]=meshgrid([1,2,4],[2,4,5])

meshgrid([1,2,4],[2,4,5])

ix_([1,2,4],[2,4,5])

лучший способ вычисления функций на сетке

repmat(a, m, n)

tile(a, (m, n))

создание m на n копий a

[a b]

concatenate((a,b),1) или hstack((a,b)) или column_stack((a,b)) или c_[a,b]

объединение столбцов a и b

[a; b]

concatenate((a,b)) или vstack((a,b)) или r_[a,b]

объединение строк a и b

max(max(a))

a.max()

максимальный элемент a (с ndims(a)<=2 для matlab)

max(a)

a.max(0)

максимальный элемент каждого столбца матрицы a

max(a,[],2)

a.max(1)

максимальный элемент каждой строки матрицы a

max(a,b)

maximum(a, b)

сравнивает a и b поэлементно и возвращает максимальное значение из каждой пары

norm(v)

sqrt(v @ v) или np.linalg.norm(v)

норма L2 вектора v

a & b

logical_and(a,b)

поэлементный оператор AND (NumPy ufunc) См. примечание LOGICOPS

a | b

logical_or(a,b)

поэлементный оператор OR (NumPy ufunc) См. примечание LOGICOPS

bitand(a,b)

a & b

битовый оператор AND (родной Python и NumPy ufunc)

bitor(a,b)

a | b

битовый оператор OR (родной Python и NumPy ufunc)

inv(a)

linalg.inv(a)

обратная матрица квадратной матрицы a

END_OF_DOCUMENT_MARKER

pinv(a)

linalg.pinv(a)

псевдообратная матрица a

rank(a)

linalg.matrix_rank(a)

ранг матрицы двумерного массива a

a\b

linalg.solve(a,b) если a является квадратной; linalg.lstsq(a,b) в противном случае

решение уравнения a x = b для x

b/a

Решить aT xT = bT вместо этого

решение уравнения x a = b для x

[U,S,V]=svd(a)

U, S, Vh = linalg.svd(a), V = Vh.T

разложение по сингулярным значениям a

chol(a)

linalg.cholesky(a).T

разложение Холецкого матрицы (chol(a) в matlab возвращает верхнюю треугольную матрицу, но linalg.cholesky(a) возвращает нижнюю треугольную матрицу)

[V,D]=eig(a)

D,V = linalg.eig(a)

собственные значения и собственные векторы a

[V,D]=eig(a,b)

D,V = scipy.linalg.eig(a,b)

собственные значения и собственные векторы a, b

[V,D]=eigs(a,k)

найти k наибольшие собственные значения и собственные векторы a

[Q,R,P]=qr(a,0)

Q,R = scipy.linalg.qr(a)

QR-разложение

[L,U,P]=lu(a)

L,U = scipy.linalg.lu(a) или LU,P=scipy.linalg.lu_factor(a)

LU-разложение (примечание: P(Matlab) == transpose(P(numpy)) )

conjgrad

scipy.sparse.linalg.cg

Решение методом сопряжённых градиентов

fft(a)

fft(a)

преобразование Фурье a

ifft(a)

ifft(a)

обратное преобразование Фурье a

sort(a)

sort(a) или a.sort()

сортировка матрицы

[b,I] = sortrows(a,i)

I = argsort(a[:,i]), b=a[I,:]

сортировка строк матрицы

regress(y,X)

linalg.lstsq(X,y)

многомерная регрессия

decimate(x, q)

scipy.signal.resample(x, len(x)/q)

уменьшение частоты с помощью фильтра низких частот

unique(a)

unique(a)

squeeze(a)

a.squeeze()

Примечания

Подматрица: Присвоение подматрице можно выполнить с помощью списков индексов, используя команду ix_. Например, для двумерного массива a, можно сделать так: ind=[1,3]; a[np.ix_(ind,ind)]+=100.

HELP: Нет прямого эквивалента команде MATLAB which, но команды help и source обычно отображают имя файла, где находится функция. В Python также есть модуль inspect (выполните import inspect), который предоставляет getfile, часто работающий аналогично.

ИНДЕКСИРОВАНИЕ: MATLAB® использует индексацию, начинающуюся с 1, поэтому начальный элемент последовательности имеет индекс 1. Python использует индексацию, начинающуюся с 0, поэтому начальный элемент последовательности имеет индекс 0. Путаница и споры возникают, потому что у каждого есть свои преимущества и недостатки. Индексация, начинающаяся с 1, соответствует обычному человеческому языку, где «первый» элемент последовательности имеет индекс 1. Индексация, начинающаяся с 0, упрощает индексацию. См. также текст проф. д-ра Эдсгера В. Дейкстры.

ДИАПАЗОНЫ: В MATLAB®, 0:5 может использоваться как литерал диапазона, так и индекс «среза» (в скобках); однако в Python конструкции типа 0:5 могут только использоваться как индексы срезов (в квадратных скобках). Таким образом, был создан несколько необычный объект r_, чтобы позволить numpy иметь аналогичный краткий механизм построения диапазонов. Обратите внимание, что r_ не вызывается как функция или конструктор, а индексируется с помощью квадратных скобок, что позволяет использовать синтаксис срезов Python в аргументах.

ЛОГИЧЕСКИЕ ОПЕРАТОРЫ: & или | в NumPy — это побитовые И/ИЛИ, а в Matlab & и | — логические И/ИЛИ. Разница должна быть очевидна для любого опытного программиста. Оба могут работать одинаково, но есть важные различия. Если вы использовали операторы & или | в Matlab, вы должны использовать функции 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() на матрице возвращает их, в то время как 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.

Настройка вашей среды

В MATLAB® основным инструментом для настройки среды является изменение пути поиска с указанием расположения ваших любимых функций. Вы можете поместить такие настройки в скрипт запуска, который MATLAB будет запускать при запуске.

NumPy, или скорее Python, имеют аналогичные возможности.

  • Чтобы изменить путь поиска Python, включив в него расположения ваших собственных модулей, определите переменную среды PYTHONPATH.
  • Чтобы при запуске интерактивного интерпретатора Python выполнить определённый скрипт, определите переменную среды PYTHONSTARTUP, содержащую имя вашего скрипта запуска.

В отличие от MATLAB®, где всё, что находится в пути, можно вызвать сразу, с Python вам сначала нужно выполнить оператор «import», чтобы сделать функции в определённом файле доступными.

Например, вы можете создать скрипт запуска, который выглядит так (Примечание: это просто пример, а не «лучшие практики»):

# Make all numpy available via shorter 'np' prefix
import numpy as np
# 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 rand,zeros,ones,empty,eye
# Define a Hermitian function
def hermitian(A, **kwargs):
    return np.transpose(A,**kwargs).conj()
# Make some shortcuts for transpose,hermitian:
#    np.transpose(A) --> T(A)
#    hermitian(A) --> H(A)
T = np.transpose
H = hermitian

Ссылки

См. http://mathesaurus.sf.net/ для другого справочника MATLAB®/NumPy.

Подробный список инструментов для научных работ с Python можно найти на странице тематических программных средств.

MATLAB® и SimuLink® — зарегистрированные товарные знаки The MathWorks.

© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.18/user/numpy-for-matlab-users.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API