在NumPy中相当于MATLAB的repmat

问题:在NumPy中相当于MATLAB的repmat

我想使用NumPy执行以下MATLAB代码的等效项:repmat([1; 1], [1 1 1])。我将如何完成?

I would like to execute the equivalent of the following MATLAB code using NumPy: repmat([1; 1], [1 1 1]). How would I accomplish this?


回答 0

对于Matlab用户,这是一个更好(官方)的NumPy链接-恐怕其中的Mathesaurus已经过时了。

的numpy的当量repmat(a, m, n)tile(a, (m, n))

这适用于多个维度,并提供与matlab类似的结果。(Numpy提供了3d输出数组,正如您期望的那样-由于某种原因,matlab提供了2d输出-但内容相同)。

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

Here is a much better (official) NumPy for Matlab Users link – I’m afraid the mathesaurus one is quite out of date.

The numpy equivalent of repmat(a, m, n) is tile(a, (m, n)).

This works with multiple dimensions and gives a similar result to matlab. (Numpy gives a 3d output array as you would expect – matlab for some reason gives 2d output – but the content is the same).

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

回答 1

请注意,NumPy的广播机制已解决了需要使用MATLAB的repmat的某些原因,该机制使您可以使用形状相似的数组进行各种类型的数学运算。因此,如果您有一个表示3色图像的1600x1400x3数组,则可以(在元素上)相乘[1.0 0.25 0.25]以减少每个像素的绿色和蓝色量。有关更多信息,请参见上面的链接。

Note that some of the reasons you’d need to use MATLAB’s repmat are taken care of by NumPy’s broadcasting mechanism, which allows you to do various types of math with arrays of similar shape. So if you had, say, a 1600x1400x3 array representing a 3-color image, you could (elementwise) multiply it by [1.0 0.25 0.25] to reduce the amount of green and blue at each pixel. See the above link for more information.


回答 2

请参阅Matlab用户的NumPy

Matlab:

repmat(a, 2, 3)

脾气暴躁:

numpy.kron(numpy.ones((2,3)), a)

Numpy中的Matlib(numpy.matlib.repmat()):

numpy.matlib.repmat(a, 2, 3)

See NumPy for Matlab users.

Matlab:

repmat(a, 2, 3)

Numpy:

numpy.kron(numpy.ones((2,3)), a)

Matlib in Numpy (numpy.matlib.repmat()):

numpy.matlib.repmat(a, 2, 3)

回答 3

这就是我有点儿摆弄的方式。很高兴得到纠正,希望能有所帮助。

假设您有2×3个元素的矩阵M。显然,这有两个方面。


当要求沿着矩阵已经具有的维度操纵输入矩阵时,我看不到Matlab和Python之间的区别。因此这两个命令

repmat(M,m,n) % matlab

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

对于等级2(二维)的矩阵实际上是等效的。


当您要求重复/平铺比输入矩阵更多的维度时,事情变得与直觉相反。回到等级2和形状2×3的矩阵M,足以看出输出矩阵的大小/形状发生了什么。假设现在的操作顺序为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不同的形状。人们可以不再断言repmattile等价指令。


为了变得tilerepmat,在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可以按Matlab的预期计算出序列(1,1,2)的阅读方式。

在元件[:,:,0]在Python答案Ñ将包含相同的值作为元素(:,:,1)Matlab的答案中号


最后,我似乎找不到repmat当人使用Kronecker产品的等效产品

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

除非我如上所述将M前提为N。因此,我认为继续前进的最一般方法是使用np.newaxis


当我们考虑等级3(三个维度)的矩阵L以及在输出矩阵中不添加任何新维度的简单情况时,游戏将变得更加棘手。这两个看似等效的指令不会产生相同的结果

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

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

因为行,列和平面外方向在Matlab中是(p,q,r)在Python中是(q,r,p),在rank-2数组中不可见。在那里,必须要小心,使用两种语言获得相同的结果将需要更多的预处理。


我知道这种推理可能不是一般性的,但我只能在目前为止得出结论。希望这会邀请其他人对其进行更严格的测试。

This is how I understood it out of a bit of fiddling around. Happy to be corrected and hope this helps.

Say you have a matrix M of 2×3 elements. This has two dimensions, obviously.


I could see no difference between Matlab and Python while asking to manipulate the input matrix along the dimensions the matrix already has. Thus the two commands

repmat(M,m,n) % matlab

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

are really equivalent for a matrix of rank 2 (two dimensions).


The matters goes counter-intuitive when you ask for repetition/tiling over more dimensions than the input matrix has. Going back to the matrix M of rank two and shape 2×3, it is sufficient to look at what happens to the size/shape of the output matrix. Say the sequence for manipulation is now 1,1,2.

In Matlab

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

    2   3   2

it has copied the first two dimensions (rows and columns) of the input matrix and has repeated that once into a new third dimension (copied twice, that is). True to the naming repmat for repeat matrix.

In Python

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

it has applied a different procedure since, I presume, the sequence (1,1,2) is read differently than in Matlab. The number of copies in the direction of columns, rows and out-of-plane dimension are being read from right to left. The resulting object has a different shape from Matlab. One can no longer assert that repmat and tile are equivalent instructions.


In order to get tile to behave like repmat, in Python one has to make sure that the input matrix has as many dimensions as the elements are in the sequence. This is done, for example, by a little preconditioning and creating a related object N

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

Then, at the input side one has N.shape = (2,3,1) rather than M.shape = (2,3) and at the output side

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

which was the answer of size(repmat(M,1,1,2)). I presume this is because we have guided Python to add the third dimension to the right of (2,3) rather than to its left, so that Python works out the sequence (1,1,2) as it was intended in the Matlab way of reading it.

The element in [:,:,0] in the Python answer for N will contain the same values as the element (:,:,1) the Matlab answer for M.


Finally, I can’t seem to find an equivalent for repmat when one uses the Kronecker product out of

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

unless I then precondition M into N as above. So I would argue that the most general way to move on is to use the ways of np.newaxis.


The game gets trickier when we consider a matrix L of rank 3 (three dimensions) and the simple case of no new dimensions being added in the output matrix. These two seemingly equivalent instructions will not produce the same results

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

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

because the row, column, out-of-plane directions are (p,q,r) in Matlab and (q,r,p) in Python, which was not visible with rank-2 arrays. There, one has to be careful and obtaining the same results with the two languages would require more preconditioning.


I am aware that this reasoning may well not be general, but I could work it out only this far. Hopefully this invites other fellows to put it to a harder test.


回答 4

认识tilerepeat

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)

Know both tile and repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)

回答 5

numpy.matlib有一个 repmat函数,其接口与matlab函数类似

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)

numpy.matlib has a repmat function with a similar interface as the matlab function

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)

回答 6

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