Який еквівалент репліки MATLAB в NumPy


103

Я хотів би виконати еквівалент наступного коду MATLAB з допомогою NumPy: repmat([1; 1], [1 1 1]). Як я це досяг?

Відповіді:


103

Ось набагато кращий (офіційний) NumPy для користувачів Matlab - я боюсь, що той, який є математичним, дуже застарів.

Нульовий еквівалент repmat(a, m, n)дорівнюєtile(a, (m, n)) .

Це працює з декількома розмірами і дає схожий результат на матлаб. (Numpy дає 3d-вихідний масив, як ви очікували - matlab чомусь дає 2d вихід - але вміст той самий).

Матлаб:

>> repmat([1;1],[1,1,1])

ans =
     1
     1

Пітон:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])

2
коли я спробую розмір (репмат ([1; 1], [1,1,2])), він отримує ans = 2 1 2 [в matlab], але в python np.tile (a, [1,1,2]) .сформуйте це (1, 2, 2), я хочу, щоб numpy дав результат такий же, як і
matlab

2
np.tile (a [:, np.newaxis], [1,1,2]) - він дає те саме. Проблема полягає в тому, що плитка сприяє aрозмірності аргументу плитки, попередньо додаючи нові осі за необхідності. Матлаб, здається, працює інакше. Точно так само з 4d плиткою вам знадобляться новинки два рази ... так, np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))як потрібно ...
robince

17

Зауважте, що з деяких причин, які вам знадобиться використовувати реплет MATLAB, опікується механізм мовлення NumPy , який дозволяє робити різні типи математики з масивами подібної форми. Отже, якби у вас, скажімо, був масив розміром 1600x1400x3, що представляє 3-кольорове зображення, ви могли б (елементарно) помножити його [1.0 0.25 0.25]на зменшення кількості зеленого та синього на кожен піксель. Для отримання додаткової інформації див. Вищенаведене посилання.


2
Не те, що Matlab може робити це мовлення також, якщо ви користуєтесь bsxfun.
gerrit


8

Ось як я це зрозумів із трохи хитрування. Раді виправитись і сподіваюся, що це допоможе.

Скажімо, у вас є матриця M з 2х3 елементів. Очевидно, це має два виміри.


Я не міг бачити різниці між Matlab та Python, просячи маніпулювати вхідною матрицею за розмірами, які матриця вже має. Таким чином, дві команди

repmat(M,m,n) % matlab

np.tile(M,(m,n)) # python

дійсно еквівалентні для матриці 2 рангу (два виміри).


Питання виходять контрінтуїтивними, коли ви запитуєте про повторення / накладання плит на більше розмірів, ніж вхідна матриця. Повертаючись до матриці M другого рангу та форми 2x3, достатньо подивитися, що відбувається з розміром / формою вихідної матриці. Скажімо, послідовність маніпуляцій зараз 1,1,2.

У Матлабі

> size(repmat(M,1,1,2))
ans =

    2   3   2

він скопіював перші два виміри (рядки та стовпці) вхідної матриці і повторив це один раз у новий третій вимір (скопійований двічі, тобто). Вірно іменуванню repmatдля повторної матриці.

У Python

>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)

він застосував іншу процедуру, оскільки, я припускаю, послідовність (1,1,2) читається інакше, ніж у Matlab. Кількість примірників у напрямку стовпців, рядків та розмірів поза площиною зчитуються справа наліво. Отриманий об'єкт має іншу форму від Matlab. Більше не можна цього стверджувати repmatі tileє рівнозначними інструкціями.


Для того, щоб tileвести себе так repmat, в Python потрібно переконатися, що вхідна матриця має стільки ж розмірів, скільки елементів у послідовності. Це робиться, наприклад, невеликою попередньою умовою та створенням пов'язаного об’єкта N

N = M[:,:,np.newaxis]

Тоді на стороні входу є одна, N.shape = (2,3,1)а не M.shape = (2,3)на вихідній стороні

>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)

що було відповіддю size(repmat(M,1,1,2)) . Я припускаю, що це тому, що ми керували Python додати третій вимір праворуч від (2,3), а не ліворуч, щоб Python розробив послідовність (1,1,2), як це було призначено в Matlab спосіб її читання.

Елемент [:,:,0]у відповідь на Python N буде містити одні і ті ж значення, що і елемент (:,:,1)відповідь Matlab для M .


Нарешті, я не можу знайти собі еквівалента, repmatколи хтось використовує продукт Kronecker

>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)

якщо я тоді не зумовив умову M на N, як зазначено вище. Тож я б заперечив, що найзагальнішим способом рухатися є використання способів np.newaxis.


Гра стає складнішою, коли ми розглядаємо матрицю L рангу 3 (три виміри) та простий випадок, коли у вихідну матрицю не додаються нові розміри. Ці дві, здавалося б, еквівалентні інструкції не дадуть однакових результатів

repmat(L,p,q,r) % matlab

np.tile(L,(p,q,r)) # python

тому що рядки, стовпці, позапланові напрямки знаходяться (p, q, r) у Matlab та (q, r, p) у Python, що не було видно з масивами ran-2. Там потрібно бути обережним, і отримання однакових результатів з двома мовами вимагатиме більше попередніх умов.


Я знаю, що ці міркування цілком можуть бути не загальними, але я міг би розробити це лише зараз. Сподіваємось, це запрошує інших стипендіатів поставити це на більш жорстке випробування.




0
>>> import numpy as np

>>> np.repeat(['a','b'], [2,5])

array(['a', 'a', 'b', 'b', 'b', 'b', 'b'], dtype='<U1')

>>> np.repeat([1,2], [2,5])

array([1, 1, 2, 2, 2, 2, 2])

>>> np.repeat(np.array([1,2]), [3]).reshape(2,3)

array([[1, 1, 1],
       [2, 2, 2]])

>>> np.repeat(np.array([1,2]), [2,4]).reshape(3,2)

array([[1, 1],
       [2, 2],
       [2, 2]])

>>> np.repeat(np.matrix('1 2; 3 4'), [2]).reshape(4,2)

matrix([[1, 1],
        [2, 2],
        [3, 3],
        [4, 4]])
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.