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 不同的形状。不能再断言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 按照 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】:知道tile
和repeat
。
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相当于啥的主要内容,如果未能解决你的问题,请参考以下文章