NumPy中MATLAB的repmat相当于啥

Posted

技术标签:

【中文标题】NumPy中MATLAB的repmat相当于啥【英文标题】:What is the equivalent of MATLAB's repmat in NumPyNumPy中MATLAB的repmat相当于什么 【发布时间】:2010-12-15 20:39:58 【问题描述】:

我想使用 NumPy 执行以下 MATLAB 代码的等效代码:repmat([1; 1], [1 1 1])。我将如何做到这一点?

【问题讨论】:

【参考方案1】:

见NumPy for Matlab users。

Matlab:

repmat(a, 2, 3)

麻木:

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

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

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

【讨论】:

【参考方案2】:
>>> 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]])

【讨论】:

【参考方案3】:

这里有一个更好的(官方)NumPy for Matlab Users 链接 - 恐怕mathesaurus 已经过时了。

repmat(a, m, n) 的 numpy 等效项是 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]]])

【讨论】:

当我尝试 size(repmat([1;1],[1,1,2])) 它得到 ans = 2 1 2 [in matlab] 但在 python np.tile(a, [1,1,2]).shape it get(1, 2, 2) ,我希望 numpy 给出与 matlab 相同的结果 np.tile(a[:,np.newaxis],[1,1,2]) - 它给出了相同的结果。问题是 tile 将 a 提升到 tile 参数的维度,方法是根据需要 preending 新轴。 Matlab 似乎以另一种方式工作。同样,使用 4d 平铺时,您将需要两次 newaxis...所以np.tile(a[:,newaxis,newaxis],[1,2,3,4]) = size(repmat(a,[1 2 3 4])) 根据需要...【参考方案4】:

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

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

【讨论】:

【参考方案5】:

这就是我通过一些摆弄来理解它的方式。很高兴得到纠正,希望对您有所帮助。

假设您有一个由 2x3 元素组成的矩阵 M。这显然有两个维度。


在要求沿矩阵已有的维度操作输入矩阵时,我看不出 Matlab 和 Python 之间没有区别。 因此这两个命令

repmat(M,m,n) % matlab

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

对于秩为 2(二维)的矩阵实际上是等价的。


当您要求在比输入矩阵更多的维度上重复/平铺时,事情就会违反直觉。回到秩为 2 且形状为 2x3 的矩阵 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 是等效的指令。


为了让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 按照 Matlab 中的预期计算出序列 (1,1,2)阅读方式。

N 的 Python 答案中 [:,:,0] 中的元素将包含与 M 的 Matlab 答案中的元素 (:,:,1) 相同的值。


最后,当有人使用 Kronecker 产品时,我似乎找不到 repmat 的等价物

>>> 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 数组是不可见的。在那里,必须小心,使用两种语言获得相同的结果需要更多的预处理。


我知道这种推理可能并不普遍,但我只能到此为止。希望这会邀请其他人对其进行更严格的测试。

【讨论】:

这是最好的答案,因为它处理了重复到新输出维度的重要情况。【参考方案6】:

知道tilerepeat

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

【讨论】:

【参考方案7】:

请注意,您需要使用 MATLAB 的 repmat 的一些原因由 NumPy 的 broadcasting 机制处理,该机制允许您对形状相似的数组进行各种类型的数学运算。因此,如果您有一个表示 3 色图像的 1600x1400x3 数组,您可以(按元素)将其乘以 [1.0 0.25 0.25] 以减少每个像素的绿色和蓝色数量。有关详细信息,请参阅上面的链接。

【讨论】:

如果你使用bsxfun,Matlab 也不能做这种广播。

以上是关于NumPy中MATLAB的repmat相当于啥的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB 图片折腾4

matlab中的reshape命令有啥数学意义?

Matlab中repmat的用法

MATLAB的repmat函数

matlab的rapmat()函数

numpy和matlab计算协方差矩阵的不同(matlab是标准的,numpy相当于转置后计算)