【问题标题】:Python: Differentiating between row and column vectorsPython:区分行向量和列向量
【发布时间】:2013-06-29 23:59:35
【问题描述】:

有没有一种区分python中行向量和列向量的好方法?到目前为止,我使用的是 numpy 和 scipy,到目前为止我看到的是,如果我要给一个向量,比如说

from numpy import *
Vector = array([1,2,3])

他们不能说天气我的意思是行或列向量。此外:

array([1,2,3]) == array([1,2,3]).transpose()
True

这在“现实世界”中是完全不真实的。 我意识到来自上述模块的向量上的大多数功能都不需要区分。例如outer(a,b)a.dot(b),但为了我自己的方便,我想区分一下。

【问题讨论】:

  • 您观察到的行为实际上是正确“在现实世界中”:一维数字序列既不是行也不是列向量。行或列向量实际上是一个 二维 维数组(其中二维之一为 1)。因此,您的测试应该使用array([[1, 2, 3]]) 来完成,而不是它的转置。
  • 这实际上在数学上不太正确。矩阵是 mxn,根据定义,行向量是 m=1 的向量,列向量是 n=1 的向量。维度在数学上完全不同,与向量空间中基组中向量的数量有关,所以实际上我们根本不应该谈论单个向量的维度。我认为谈论“现实世界”的原始海报是在谈论线性代数和数学的世界,所以是正确的。程序员往往会错误地使用这些术语。
  • @neuronet,这实际上在数学上并不完全正确。您所描述的是事物的方式,例如在 Matlab 中,这是一个非常有用的约定。数学上正确的方法是区分来自给定空间的向量(按约定表示为列)和来自其dual space 的向量(按约定表示为行)。

标签: python arrays numpy vector scipy


【解决方案1】:

您可以通过向数组添加另一个维度来明确区分。

>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.transpose()
array([1, 2, 3])
>>> a.dot(a.transpose())
14

现在强制它为列向量:

>>> a.shape = (3,1)
>>> a
array([[1],
       [2],
       [3]])
>>> a.transpose()
array([[1, 2, 3]])
>>> a.dot(a.transpose())
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

当你想要区分时,另一种选择是使用 np.newaxis:

>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a[:, np.newaxis]
array([[1],
       [2],
       [3]])
>>> a[np.newaxis, :]
array([[1, 2, 3]])

【讨论】:

  • 我想过,但这意味着 getitem 变得不一致:a[0] = [1]a[0][0] = 1 用于列向量,a[0] = 1a[0][0] = TypeError 用于行向量。
  • 是的,这是您必须考虑的权衡。另一种选择是在需要区分时使用 np.newaxis(请参阅我的答案的编辑)。
  • 另一种将行向量(一维数组)转换为列向量(返回副本)的方法:a.reshape(a.size, 1),如果你像我一样懒惰,甚至是a.reshape(-1, 1)
【解决方案2】:

在编写向量时使用双精度 []

那么,如果你想要一个行向量:

row_vector = array([[1, 2, 3]])    # shape (1, 3)

或者如果你想要一个列向量:

col_vector = array([[1, 2, 3]]).T  # shape (3, 1)

【讨论】:

  • 谢谢你这好多了:D
【解决方案3】:

您正在创建的向量既不是行也不是列。它实际上只有一维。您可以通过

来验证
  • 检查维数myvector.ndim,即1
  • 检查myvector.shape,即(3,)(只有一个元素的元组)。对于行向量应该是(1, 3),对于一列应该是(3, 1)

两种处理方式

  • 创建一个实际行或列向量
  • reshape你现在的人

您可以显式创建行或列

row = np.array([    # one row with 3 elements
   [1, 2, 3]
]
column = np.array([  # 3 rows, with 1 element each
    [1],
    [2],
    [3]
])

或者,使用快捷方式

row = np.r_['r', [1,2,3]]     # shape: (1, 3)
column = np.r_['c', [1,2,3]]  # shape: (3,1)

或者,您可以将其重塑为 (1, n) 用于行,或 (n, 1) 用于列

row = my_vector.reshape(1, -1)
column = my_vector.reshape(-1, 1)

-1 自动查找n 的值。

【讨论】:

  • 但如果既不是行也不是列,矩阵乘法的结果是什么?例如A 是 2x2,b 是长度为 2 的数组。那么 A @ b 是什么?所以我们在那个例子中看到 b 必须是一个列向量!
  • @LorisFoe: b @ A 也提供了一些东西。通过该示例,我们看到它不能是列向量。查找广播
【解决方案4】:

我认为你可以使用 numpy.array 的 ndmin 选项。将其保持为 2 表示它将是 (4,1) 而转置将是 (1,4)。

>>> a = np.array([12, 3, 4, 5], ndmin=2)
>>> print a.shape
>>> (1,4)
>>> print a.T.shape
>>> (4,1)

【讨论】:

    【解决方案5】:

    如果您想对这种情况进行区分,我建议您改用matrix,其中:

    matrix([1,2,3]) == matrix([1,2,3]).transpose()
    

    给予:

    matrix([[ True, False, False],
            [False,  True, False],
            [False, False,  True]], dtype=bool)
    

    您还可以使用ndarray 显式添加第二个维度:

    array([1,2,3])[None,:]
    #array([[1, 2, 3]])
    

    和:

    array([1,2,3])[:,None]
    #array([[1],
    #       [2],
    #       [3]])
    

    【讨论】:

    • array([1,2,3])[None,:] 比显式的array([[1, 2, 3]]) 复杂得多。
    • matrix 通常值得避免,因为它不能推广到更高的维度
    【解决方案6】:

    您可以将数组的元素存储在一行或一列中,如下所示:

    >>> a = np.array([1, 2, 3])[:, None] # stores in rows
    >>> a
    array([[1],
           [2],
           [3]])
    
    >>> b = np.array([1, 2, 3])[None, :] # stores in columns
    >>> b
    array([[1, 2, 3]])
    

    【讨论】:

      【解决方案7】:

      如果我想要一个 1x3 数组,或者 3x1 数组:

      import numpy as np
      row_arr = np.array([1,2,3]).reshape((1,3))
      col_arr = np.array([1,2,3]).reshape((3,1)))
      

      检查你的工作:

      row_arr.shape  #returns (1,3)
      col_arr.shape  #returns (3,1)
      

      我发现这里有很多答案很有帮助,但对我来说太复杂了。在实践中,我回到shapereshape,代码是可读的:非常简单和明确。

      【讨论】:

        【解决方案8】:

        看起来 Python 的 Numpy 不区分它,除非你在上下文中使用它:

        “如果你愿意,你可以有标准向量或行/列向量。”

        " :) 您可以将 rank-1 数组视为行向量或列向量。dot(A,v) 将 v 视为列向量,而 dot(v,A) 将 v 视为行向量。这可以节省你必须输入很多转置。"

        另外,特定于您的代码:“在 rank-1 数组上转置什么都不做。” 资源: http://wiki.scipy.org/NumPy_for_Matlab_Users

        【讨论】:

        • 我知道。我想要一种方法来区分它们。也许其他一些数学模块?
        【解决方案9】:

        当我尝试使用 numpy 计算 w^T * x 时,我也感到非常困惑。事实上,我自己无法实现它。因此,这是我们需要熟悉的 NumPy 中为数不多的问题之一。

        一维数组而言,行向量和列向量没有区别。它们完全一样。

        看下面的例子,我们在所有情况下都得到相同的结果,这在(理论意义上的)线性代数中是不正确的:

        In [37]: w
        Out[37]: array([0, 1, 2, 3, 4])
        
        In [38]: x
        Out[38]: array([1, 2, 3, 4, 5])
        
        In [39]: np.dot(w, x)
        Out[39]: 40
        
        In [40]: np.dot(w.transpose(), x)
        Out[40]: 40
        
        In [41]: np.dot(w.transpose(), x.transpose())
        Out[41]: 40
        
        In [42]: np.dot(w, x.transpose())
        Out[42]: 40
        

        有了这些信息,现在让我们尝试计算向量 |w|^2 的平方长度。

        为此,我们需要将w 转换为二维数组。

        In [51]: wt = w[:, np.newaxis]
        
        In [52]: wt
        Out[52]: 
        array([[0],
               [1],
               [2],
               [3],
               [4]])
        

        现在,让我们计算向量w 的平方长度(或平方大小):

        In [53]: np.dot(w, wt)
        Out[53]: array([30])
        

        请注意,我们使用wwt 而不是wtw(就像在理论线性代数中一样),因为形状与 np.dot(wt, w) 的使用不匹配。因此,我们将向量的平方长度设为[30]。也许这是区分(numpy的解释)行和列向量的方法之一?

        最后,我有没有提到我找到了实现 w^T * x 的方法?是的,我做到了:

        In [58]: wt
        Out[58]: 
        array([[0],
               [1],
               [2],
               [3],
               [4]])
        
        In [59]: x
        Out[59]: array([1, 2, 3, 4, 5])
        
        In [60]: np.dot(x, wt)
        Out[60]: array([40])
        

        因此,在 NumPy 中,操作数的顺序是颠倒的,如上所示,这与我们在理论线性代数中研究的相反。


        附注potential gotchas in numpy

        【讨论】:

        • 如果您尝试在一维数组列表上执行np.hstacknp.vstack,它确实会有所作为!如果每个数组的形状为(10, ),则hstack 的结果为(20,)vstack 的结果为(2, 10)。这意味着它们被假定为列向量!
        【解决方案10】:

        这是另一种直观的方式。假设我们有:

        >>> a = np.array([1, 3, 4])
        >>> a
        array([1, 3, 4])
        

        首先我们创建一个二维数组,将其作为唯一的行:

        >>> a = np.array([a])
        >>> a
        array([[1, 3, 4]])
        

        然后我们可以转置它:

        >>> a.T
        array([[1],
               [3],
               [4]])
        

        【讨论】:

          【解决方案11】:

          行向量是 (1,0) 张量,向量是 (0, 1) 张量。如果使用 v = np.array([[1,2,3]]),v 变为 (0,2) 张量。对不起,我很困惑。

          【讨论】:

            【解决方案12】:

            出色的 Pandas 库为 numpy 添加了功能,使此类操作更加直观 IMO。例如:

            import numpy as np
            import pandas as pd
            
            # column
            df = pd.DataFrame([1,2,3])
            
            # row
            df2 = pd.DataFrame([[1,2,3]])
            

            你甚至可以define a DataFrame and make a spreadsheet-like pivot table

            【讨论】:

            • 因为您可以在 NumPy 中编写相同的内容,所以我要补充一个重要的事实,即在考虑行向量和列向量时,df[0] = 10df2[0] = 10 都按预期工作。这就是 Pandas 比 NumPy 更方便的地方。
            猜你喜欢
            • 1970-01-01
            • 2020-07-14
            • 2011-01-26
            • 2015-05-23
            • 2019-12-17
            • 2014-02-18
            • 1970-01-01
            • 1970-01-01
            • 2023-03-10
            相关资源
            最近更新 更多