Что эквивалентно MATLAB repmat в NumPy

103

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

Vernomcrp
источник

Ответы:

103

Вот гораздо лучшая (официальная) ссылка на NumPy для пользователей Matlab - я боюсь, что ссылка на mathesaurus довольно устарела.

NumPy эквивалент repmat(a, m, n)это tile(a, (m, n)).

Это работает с несколькими измерениями и дает результат, аналогичный Matlab. (Numpy дает трехмерный выходной массив, как и следовало ожидать - Matlab по какой-то причине дает 2-мерный вывод - но содержимое такое же).

Matlab:

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

ans =
     1
     1

Python:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])
Робинс
источник
2
когда я пробую size (repmat ([1; 1], [1,1,2])), он получает ans = 2 1 2 [в matlab], но в python np.tile (a, [1,1,2]) .shape it get (1, 2, 2), я хочу, чтобы numpy давал такой же результат, как и matlab
vernomcrp
2
np.tile (a [:, np.newaxis], [1,1,2]) - дает то же самое. Проблема в том, что плитка увеличивает aразмер аргумента плитки, добавляя при необходимости новые оси. Matlab, похоже, работает по-другому. Точно так же с 4d мозаикой вам понадобится новая ось дважды ... так что по np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4]))мере необходимости ...
robince
17

Обратите внимание, что некоторые из причин, по которым вам нужно использовать repmat MATLAB, заботятся о механизме вещания NumPy , который позволяет вам выполнять различные типы математики с массивами аналогичной формы. Итак, если бы у вас был, скажем, массив 1600x1400x3, представляющий трехцветное изображение, вы могли бы (поэлементно) умножить его на, [1.0 0.25 0.25]чтобы уменьшить количество зеленого и синего в каждом пикселе. См. Ссылку выше для получения дополнительной информации.

Kwatford
источник
2
Не то чтобы Matlab также мог делать это трансляцию, если вы используете bsxfun.
gerrit
8

Вот как я понял это, немного возясь. Рад, что вас исправят, и надеюсь, что это поможет.

Скажем, у вас есть матрица M из 2x3 элементов. Очевидно, это имеет два измерения.


Я не видел разницы между Matlab и Python, когда просил манипулировать входной матрицей по размерам, которые матрица уже имеет. Таким образом, две команды

repmat(M,m,n) % matlab

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

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


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

В Matlab

> 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когда кто-то использует продукт Кронекера вне

>>> 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, что не было видно с массивами ранга 2. Здесь нужно быть осторожным, и получение тех же результатов с двумя языками потребует дополнительных предварительных условий.


Я понимаю, что это рассуждение может не быть общим, но я смог проработать его только до сих пор. Надеюсь, это побудит других пройти более сложное испытание.

XavierStuvw
источник
6

Знайте и то, tileи другое repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
Стив Тхоа
источник
1

numpy.matlib имеет функцию repmat с таким же интерфейсом, что и функция matlab

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
e-malito
источник
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]])
Shivid
источник