【问题标题】:numpy column arrays and strange resultsnumpy 列数组和奇怪的结果
【发布时间】:2015-06-09 17:00:23
【问题描述】:

我正在尝试编写一个函数,其参数是具有不同形状的数组。我在理解列数组和使我的函数适用于所有形状的数组时遇到了一些麻烦,以下是我发现的问题:

转置: 如果参数数组A 不是向量,那么我可以使用A.T 很好地转置它,但是如果A 是行向量,这不会将A 转换为列向量。如果A 是列向量,这将(奇怪地)将其转换为行向量。有没有办法独立于其形状转置数组?

点积 列向量与标量的点积是列向量(是的!)。列向量与 1 元素 numpy 数组的点积是行向量 (nayyy)。

A = array((1,2)).reshape(2,1) #this is how I make a column vector (is there a better looking way?)
print dot(A,3) #column vector
b = dot(array((2,4)),a) #array with shape (1,)
print dot(A,b) #row vector..(bah)

反转

linalg.inv(array(2)) #gives an error, shouldn't it return 1/2 ?

感谢大家的帮助! 附言抱歉我是菜鸟,我习惯了 Matlab 这种写东西的方式让我很困惑.. P.S.2 我不想使用矩阵,因为数组更通用

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    如果你习惯了 Matlab,Numpy 处理“列”和“行”向量的方式有点奇怪。要意识到的是,一维数组既不是列也不是行向量。要成为列或行向量,数组必须是一维设置为一的二维数组。您可以通过查看有多少个大括号来区分一维数组和一行二维数组:

    >>> a = numpy.arange(15)
    >>> a
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
    >>> b = a.reshape(1, -1)
    >>> b
    array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14]])
    

    现在你可以看到,当你转置这两个时,a 保持不变,但b 变成了一个列向量:

    >>> a.T
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
    >>> b.T
    array([[ 0],
           [ 1],
           [ 2],
           [ 3],
           [ 4],
           [ 5],
           [ 6],
           [ 7],
           [ 8],
           [ 9],
           [10],
           [11],
           [12],
           [13],
           [14]])
    

    同样,这看起来有点奇怪——但正如您所说,“数组更通用”。为了达到这种普遍性,Numpy 严格区分不同维度的数组。一维数组根本不可能是任何有意义的“列”或“行”向量。根本没有定义第二个维度!

    您的其他问题的答案来自此观察。您上面的代码示例代码为我生成了一个错误,所以我会做一些稍微不同的事情......这也会产生一个错误,但信息量更大:

    >>> A
    array([[1],
           [2]])
    >>> B
    array([2, 4])
    >>> numpy.dot(A, B)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: objects are not aligned
    

    Numpy 抱怨对象没有对齐。那是因为 B 是一维数组!让我们把它变成一个真正的行向量:

    >>> B = B.reshape(1, -1)
    >>> B
    array([[2, 4]])
    >>> numpy.dot(A, B)
    array([[2, 4],
           [4, 8]])
    >>> numpy.dot(B, A)
    array([[10]])
    

    现在一切都说得通了。 Dot 在这里简单地执行矩阵乘法;该操作按一个顺序生成一个 2x2 数组;另一方面,它产生一个 1x1 数组。注意大括号的数量!这两个都是 2-d 数组。反过来,10[10][[10]] 都将是不同的结果。

    同样,考虑这三个值:

    >>> numpy.array(2)
    array(2)
    >>> numpy.array((2,))
    array([2])
    >>> numpy.array((2,)).reshape(1,-1)
    array([[2]])
    

    如果你将这些传递给numpy.linalg.inv,除了最后一个之外,你会得到所有错误——你不能取非矩阵的矩阵逆!如果通过最后一个,结果也是一个矩阵:

    >>> numpy.linalg.inv(numpy.array((2,)).reshape(1,-1))
    array([[ 0.5]])
    

    【讨论】:

    • 现在一切都变得非常合理了。非常感谢
    【解决方案2】:

    转置

    区分一维数组和二维数组很重要。您所指的行向量是一维的,而列向量是二维的。为了演示差异,请查看以下示例。

    首先我们演示转置二维数组的默认行为(即使列向量也是一个简单的二维数组):

    import numpy as np
    
    print np.ones((3, 4)).T.shape
    print np.ones((3, 1)).T.shape
    

    输出是 - 正如预期的那样:

    (4, 3)
    (1, 3)
    

    然而,一维向量不会改变其大小:

    print np.ones((3,)).T.shape
    

    输出:

    (3,)
    

    要快速将其转换为二维数组,请使用[:,None]

    print np.ones((3,))[:,None].T.shape
    

    输出:

    (1, 3)
    

    点积

    要获得所需的结果,您应该更好地使用 2D 数组:

    A = np.ones((2, 1)     # column vector
    b = np.ones((1, 1))    # scalar
    print np.dot(A, b)     # column vector (as expected)
    

    输出:

    [[ 1.]
     [ 1.]]
    

    是的! :)

    反转

    同样,您需要确保使用二维数组。这可以使用ndmin 参数来完成:

    print np.linalg.inv(np.array(2,ndmin=2))
    

    输出:

    [[ 0.5]]
    

    【讨论】:

      猜你喜欢
      • 2021-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      • 2022-08-17
      相关资源
      最近更新 更多