首页 文章

“克隆”行或列向量

提问于
浏览
108

有时将行或列向量“克隆”到矩阵是有用的 . 通过克隆我的意思是转换行向量,如

[1,2,3]

进入矩阵

[[1,2,3]
 [1,2,3]
 [1,2,3]
]

或列向量,如

[1
 2
 3
]

[[1,1,1]
 [2,2,2]
 [3,3,3]
]

在matlab或octave中,这很容易完成:

x = [1,2,3]
 a = ones(3,1) * x
 a =

    1   2   3
    1   2   3
    1   2   3

 b = (x') * ones(1,3)
 b =

    1   1   1
    2   2   2
    3   3   3

我想在numpy中重复这个,但没有成功

In [14]: x = array([1,2,3])
In [14]: ones((3,1)) * x
Out[14]:
array([[ 1.,  2.,  3.],
       [ 1.,  2.,  3.],
       [ 1.,  2.,  3.]])
# so far so good
In [16]: x.transpose() * ones((1,3))
Out[16]: array([[ 1.,  2.,  3.]])
# DAMN
# I end up with 
In [17]: (ones((3,1)) * x).transpose()
Out[17]:
array([[ 1.,  1.,  1.],
       [ 2.,  2.,  2.],
       [ 3.,  3.,  3.]])

为什么第一种方法(In [16])不起作用?有没有办法以更优雅的方式在python中实现这个任务?

7 回答

  • 32

    这是一种优雅的Pythonic方式:

    >>> array([[1,2,3],]*3)
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    
    >>> array([[1,2,3],]*3).transpose()
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    

    [16] 的问题似乎是转置对数组没有影响 . 你可能想要一个矩阵代替:

    >>> x = array([1,2,3])
    >>> x
    array([1, 2, 3])
    >>> x.transpose()
    array([1, 2, 3])
    >>> matrix([1,2,3])
    matrix([[1, 2, 3]])
    >>> matrix([1,2,3]).transpose()
    matrix([[1],
            [2],
            [3]])
    
  • 59

    使用numpy.tile

    >>> tile(array([1,2,3]), (3, 1))
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    

    或重复列:

    >>> tile(array([[1,2,3]]).transpose(), (1, 3))
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    
  • 222

    首先请注意,通过numpy的广播操作,通常不需要复制行和列 . 有关说明,请参阅thisthis .

    但要做到这一点,repeatnewaxis可能是最好的方法

    In [12]: x = array([1,2,3])
    
    In [13]: repeat(x[:,newaxis], 3, 1)
    Out[13]: 
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    
    In [14]: repeat(x[newaxis,:], 3, 0)
    Out[14]: 
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    

    此示例适用于行向量,但将此应用于列向量有望显而易见 . 重复似乎拼写得很好,但你也可以通过乘法来实现,就像在你的例子中一样

    In [15]: x = array([[1, 2, 3]])  # note the double brackets
    
    In [16]: (ones((3,1))*x).transpose()
    Out[16]: 
    array([[ 1.,  1.,  1.],
           [ 2.,  2.,  2.],
           [ 3.,  3.,  3.]])
    
  • 8

    我认为在numpy中使用广播是最好的,也是更快的

    我做了如下比较

    import numpy as np
    b = np.random.randn(1000)
    In [105]: %timeit c = np.tile(b[:, newaxis], (1,100))
    1000 loops, best of 3: 354 µs per loop
    
    In [106]: %timeit c = np.repeat(b[:, newaxis], 100, axis=1)
    1000 loops, best of 3: 347 µs per loop
    
    In [107]: %timeit c = np.array([b,]*100).transpose()
    100 loops, best of 3: 5.56 ms per loop
    

    使用广播的速度提高了约15倍

  • 5

    np.broadcast_to 甚至比 np.tile 更快:

    x = np.arange(9)
    
    %timeit np.broadcast_to(x, (6,9))
    100000 loops, best of 3: 3.6 µs per loop
    
    %timeit np.tile(x, (6,1))
    100000 loops, best of 3: 8.4 µs per loop
    

    但最快的是@ tom10的方法:

    %timeit np.repeat(x[np.newaxis, :], 6, axis=0) 
    100000 loops, best of 3: 3.15 µs per loop
    
  • 2

    您可以使用

    np.tile(x,3).reshape((4,3))
    

    tile将生成向量的reps

    并重塑将赋予它你想要的形状

  • 0
    import numpy as np
    x=np.array([1,2,3])
    y=np.multiply(np.ones((len(x),len(x))),x).T
    print(y)
    

    收益率:

    [[ 1.  1.  1.]
     [ 2.  2.  2.]
     [ 3.  3.  3.]]
    

相关问题