简体   繁体   English

numpy.tile不能作为Matlab repmat工作

[英]numpy.tile did not work as Matlab repmat

According to What is the equivalent of MATLAB's repmat in NumPy , I tried to build 3x3x5 array from 3x3 array using python. 根据NumPy中相当于MATLAB的repmat的内容 ,我尝试使用python从3x3数组构建3x3x5数组。

In Matlab, this work as I expected. 在Matlab中,这项工作符合我的预期。

a = [1,1,1;1,2,1;1,1,1];
a_= repmat(a,[1,1,5]);

size(a_) = 3 3 5 大小(a_)= 3 3 5

But for numpy.tile 但是对于numpy.tile

b = numpy.array([[1,1,1],[1,2,1],[1,1,1]])
b_ = numpy.tile(b, [1,1,5])

b_.shape = (1, 3, 15) b_.shape =(1、3、15)

If I want to generate the same array as in Matlab, what is the equivalent? 如果要生成与Matlab中相同的数组,等效项是什么?

Edit 1 编辑1

The output I would expect to get is 我期望得到的输出是

b_(:,:,1) =

1 1 1  
1 2 1  
1 1 1  

b_(:,:,2) =

1 1 1  
1 2 1  
1 1 1  

b_(:,:,3) =

1 1 1  
1 2 1  
1 1 1  

b_(:,:,4) =  

1 1 1  
1 2 1  
1 1 1  
b_(:,:,5) =

1 1 1  
1 2 1  
1 1 1  

but what @farenorth and the numpy.dstack give is 但是@farenorth和numpy.dstack给出的是

[[[1 1 1 1 1]  
[1 1 1 1 1]  
[1 1 1 1 1]]  

[[1 1 1 1 1]  
[2 2 2 2 2]  
[1 1 1 1 1]]  

[[1 1 1 1 1]  
[1 1 1 1 1]  
[1 1 1 1 1]]]  

NumPy functions are not, in general, 'drop-in' replacements for matlab functions. 通常,NumPy函数不能替代Matlab函数。 Often times there are subtle difference to how the 'equivalent' functions are used. 通常,“等效”函数的使用方式之间存在细微的差异。 It does take time to adapt, but I've found the transition to be very worthwhile. 适应确实需要时间,但是我发现过渡非常值得。

In this case, the np.tile documentation indicates what happens when you are trying to tile an array to higher dimensions than it is defined, 在这种情况下, np.tile文档会指出当您尝试将数组平铺到比定义的数组更大的维度时会发生什么,

numpy.tile(A, reps) numpy.tile(A,代表)

Construct an array by repeating A the number of times given by reps. 通过重复A代表次数来构造一个数组。

If reps has length d, the result will have dimension of max(d, A.ndim). 如果代表的长度为d,则结果的尺寸将为max(d,A.ndim)。

If A.ndim < d, A is promoted to be d-dimensional by prepending new axes. 如果A.ndim <d,则通过添加新轴将A提升为d维。 So a shape (3,) array is promoted to (1, 3) for 2-D replication, or shape (1, 1, 3) for 3-D replication. 因此,将形状(3,)阵列提升为(1,3)以进行2D复制,或将形状(1、1、3)提升为3D复制。 If this is not the desired behavior, promote A to d-dimensions manually before calling this function. 如果这不是所需的行为,请在调用此函数之前手动将A提升为d维。

In this case, your array is being cast to a shape of [1, 3, 3] , then being tiled. 在这种情况下,将数组转换为[1, 3, 3] 1、3、3 [1, 3, 3]的形状,然后对其进行平铺。 So, to get your desired behavior just be sure to append a new singleton-dimension to the array where you want it, 因此,要获得所需的行为,只需确保将新的单例维度添加到所需数组中即可,

>>> b_ = numpy.tile(b[..., None], [1, 1, 5])
>>> print(b_.shape)
(3, 3, 5)

Note here that I've used None (ie np.newaxis ) and ellipses notation to specify a new dimension at the end of the array. 注意这里我使用了None (即np.newaxis )和省略号来在数组末尾指定一个新维度。 You can find out more about these capabilities here . 您可以在此处找到有关这些功能的更多信息。

Another option, which is inspired by the OP's comment would be: 受到OP的评论启发的另一种选择是:

b_ = np.dstack((b, ) * 5)

In this case, I've used tuple multiplication to 'repmat' the array, which is then constructed by np.dstack . 在这种情况下,我使用了元组乘法来“ repmat”该数组,然后由np.dstack构造该数组。

As @hpaulj indicated, Matlab and NumPy display matrices differently. 如@hpaulj所示,Matlab和NumPy显示矩阵的方式不同。 To replicate the Matlab output you can do something like: 要复制Matlab输出,您可以执行以下操作:

>>> for idx in xrange(b_.shape[2]):
...    print 'b_[:, :, {}] = \n{}\n'.format(idx, str(b_[:, :, idx]))
...
b_[:, :, 0] = 
[[1 1 1]
 [1 2 1]
 [1 1 1]]

b_[:, :, 1] = 
[[1 1 1]
 [1 2 1]
 [1 1 1]]

b_[:, :, 2] = 
[[1 1 1]
 [1 2 1]
 [1 1 1]]

b_[:, :, 3] = 
[[1 1 1]
 [1 2 1]
 [1 1 1]]

b_[:, :, 4] = 
[[1 1 1]
 [1 2 1]
 [1 1 1]]

Good luck! 祝好运!

Let's try the comparison, taking care to diversify the shapes and values. 让我们尝试比较,注意使形状和值多样化。

octave:7> a=reshape(0:11,3,4)
a =
    0    3    6    9
    1    4    7   10
    2    5    8   11

octave:8> repmat(a,[1,1,2])
ans =
ans(:,:,1) =
    0    3    6    9
    1    4    7   10
    2    5    8   11
ans(:,:,2) =    
    0    3    6    9
    1    4    7   10
    2    5    8   11

numpy equivalent - more or less: numpy当量-或多或少:

In [61]: a=np.arange(12).reshape(3,4)    
In [62]: np.tile(a,[2,1,1])
Out[62]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]]])

numpy again, but with order F to better match the MATLAB Fortran-derived layout 再次为numpy,但order F以更好地匹配MATLAB Fortran派生的布局

In [63]: a=np.arange(12).reshape(3,4,order='F')    
In [64]: np.tile(a,[2,1,1])
Out[64]: 
array([[[ 0,  3,  6,  9],
        [ 1,  4,  7, 10],
        [ 2,  5,  8, 11]],

       [[ 0,  3,  6,  9],
        [ 1,  4,  7, 10],
        [ 2,  5,  8, 11]]])

I'm adding the new numpy dimension at the start, because in many ways it better replicates the MATLAB practice of adding it at the end. 我在开始时添加了新的numpy维度,因为它在许多方面都更好地复制了在末尾添加它的MATLAB实践。

Try adding the new dimension at the end. 尝试在最后添加新尺寸。 The shape is (3,4,5), but you might not like the display. 形状为(3,4,5),但您可能不喜欢该显示。

 np.tile(a[:,:,None],[1,1,2])

Another consideration - what happens when you flatten the tile? 另一个考虑因素-展平瓷砖时会发生什么?

octave:10> repmat(a,[1,1,2])(:).'
ans =    
    0    1    2    3    4    5    6    7    8    9   10   11 
0    1    2    3     4    5    6    7    8    9   10   11

with the order F a 用命令F a

In [78]: np.tile(a[:,:,None],[1,1,2]).flatten()
Out[78]: 
array([ 0,  0,  3,  3,  6,  6,  9,  9,  1,  1,  4,  4,  7,  7, 10, 10,  2,
        2,  5,  5,  8,  8, 11, 11])

In [79]: np.tile(a,[2,1,1]).flatten()
Out[79]: 
array([ 0,  3,  6,  9,  1,  4,  7, 10,  2,  5,  8, 11,  0,  3,  6,  9,  1,
        4,  7, 10,  2,  5,  8, 11])

with a C order array: 与C阶数组:

In [80]: a=np.arange(12).reshape(3,4)

In [81]: np.tile(a,[2,1,1]).flatten()
Out[81]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,
        5,  6,  7,  8,  9, 10, 11])

This last one matches the Octave layout. 最后一个匹配八度布局。

So does: 也是如此:

In [83]: a=np.arange(12).reshape(3,4,order='F')

In [84]: np.tile(a[:,:,None],[1,1,2]).flatten(order='F')
Out[84]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,
        5,  6,  7,  8,  9, 10, 11])

Confused yet? 感到困惑了吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM