Spec-Zone.ru › NumPy 1.19

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

Linear Algebra Equivalents

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()

преобразование массива в вектор (обратите внимание, что это принудительно создаёт копию). Чтобы получить такой же порядок данных, как в MATLAB, используйте x.flatten('F').

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, заполненный нулями с плавающей точкой двойной точности

zeros(3,4,5)

zeros((3,4,5))

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

ones(3,4)

ones((3,4))

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

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 (ufunc NumPy) См. примечание LOGICOPS

a | b

logical_or(a,b)

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

bitand(a,b)

a & b

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

bitor(a,b)

a | b

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

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

Решить a.T x.T = b.T вместо этого

решение уравнения 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.

Справка: Нет прямого эквивалента команде MATLAB which, но команды help и 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 & или |, вы должны использовать ufuncs 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. Если вы просто переходите к линейной последовательности и обратно, это не имеет значения. Но если вы переходите от кода 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.19/user/numpy-for-matlab-users.html

Spec-Zone.ru

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