当前位置: 首页 > 知识库问答 >
问题:

numpy.array形状(R,1)和(R,)之间的差异

郏正信
2023-03-14

numpy中,有些操作以(R,1)的形式返回,但有些操作返回(R,)。这将使矩阵乘法更加繁琐,因为需要显式重塑。例如,给定一个矩阵M,如果我们想做numpy.dot(M[:,0],numpy.ones((1,R)),其中R是行数(当然,同样的问题也会在列中出现)。我们将得到矩阵未对齐错误,因为M[:,0]处于形状(R,)numpy。其中((1,R))处于形状(1,R)

因此,我的问题是:

>

  • 形状(R,1)(R,)有什么区别。我知道从字面上看,这是一个数字列表,所有列表都只包含一个数字。只是想知道为什么不设计Numpy,这样它就更喜欢形状(R,1)而不是(R,),以便更容易进行矩阵乘法。

    上面的例子还有更好的方法吗?没有像这样显式地重塑:numpy.dot(M[:,0]. reshape(R,1),numpy.ones((1, R))


  • 共有3个答案

    井兴怀
    2023-03-14

    形状是一个元组。如果只有一个尺寸,形状将是一个数字,逗号后为空。对于二维,所有逗号后都会有一个数字。

    # 1 dimension with 2 elements, shape = (2,). 
    # Note there's nothing after the comma.
    z=np.array([  # start dimension
        10,       # not a dimension
        20        # not a dimension
    ])            # end dimension
    print(z.shape)
    

    (2,)

    # 2 dimensions, each with 1 element, shape = (2,1)
    w=np.array([  # start outer dimension 
        [10],     # element is in an inner dimension
        [20]      # element is in an inner dimension
    ])            # end outer dimension
    print(w.shape)
    

    (2,1)

    仇建茗
    2023-03-14

    (R,)(1,R)之间的区别是您需要使用的索引数。one((1,R))是一个恰好只有一行的二维数组。one(R)是一个向量。一般来说,如果变量有多个行/列是没有意义的,那么应该使用向量,而不是具有单维度的矩阵。

    对于您的具体情况,有两种选择:

    1) 把第二个参数设为向量。以下工作很好:

        np.dot(M[:,0], np.ones(R))
    

    2) 如果希望使用类似matlab的矩阵运算,请使用类matrix而不是ndarray。所有矩阵都被强制为二维数组,运算符*执行矩阵乘法而不是元素乘法(因此不需要点)。根据我的经验,这是一个更麻烦的问题,但如果你习惯了matlab,它可能会更好。

    章琛
    2023-03-14

    你写道,“我知道字面上这是一个数字列表,所有列表都只包含一个数字”,但这是一种无益的思考方式。

    考虑NumPy数组的最佳方式是,它们由两部分组成,一个数据缓冲区(只是一个原始元素块)和一个描述如何解释数据缓冲区的视图。

    例如,如果我们创建一个由12个整数组成的数组:

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

    然后,a由一个数据缓冲区组成,按如下方式排列:

    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    以及描述如何解释数据的视图:

    >>> a.flags
      C_CONTIGUOUS : True
      F_CONTIGUOUS : True
      OWNDATA : True
      WRITEABLE : True
      ALIGNED : True
      UPDATEIFCOPY : False
    >>> a.dtype
    dtype('int64')
    >>> a.itemsize
    8
    >>> a.strides
    (8,)
    >>> a.shape
    (12,)
    

    这里的形状(12,)表示数组由一个从0开始运行的索引索引

    i= 0    1    2    3    4    5    6    7    8    9   10   11
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    如果我们重塑一个数组,这不会改变数据缓冲区。相反,它创建了一个新的视图,该视图描述了解释数据的不同方式。因此,在:

    >>> b = a.reshape((3, 4))
    

    数组b具有与a相同的数据缓冲区,但是现在它由两个索引索引,从0开始运行

    i= 0    0    0    0    1    1    1    1    2    2    2    2
    j= 0    1    2    3    0    1    2    3    0    1    2    3
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    这意味着:

    >>> b[2,1]
    9
    

    您可以看到第二个索引变化很快,而第一个索引变化很慢。如果您希望相反,可以指定order参数:

    >>> c = a.reshape((3, 4), order='F')
    

    这导致一个数组索引如下:

    i= 0    1    2    0    1    2    0    1    2    0    1    2
    j= 0    0    0    1    1    1    2    2    2    3    3    3
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    这意味着:

    >>> c[2,1]
    5
    

    现在应该很清楚数组具有一个或多个尺寸的形状意味着什么

    >>> d = a.reshape((12, 1))
    

    数组d由两个索引索引,第一个索引从0开始运行

    i= 0    1    2    3    4    5    6    7    8    9   10   11
    j= 0    0    0    0    0    0    0    0    0    0    0    0
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    所以:

    >>> d[10,0]
    10
    

    长度的尺寸

    >>> e = a.reshape((1, 2, 1, 6, 1))
    

    给出一个如下索引的数组:

    i= 0    0    0    0    0    0    0    0    0    0    0    0
    j= 0    0    0    0    0    0    1    1    1    1    1    1
    k= 0    0    0    0    0    0    0    0    0    0    0    0
    l= 0    1    2    3    4    5    0    1    2    3    4    5
    m= 0    0    0    0    0    0    0    0    0    0    0    0
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

    所以:

    >>> e[0,1,0,0,0]
    6
    

    有关如何实现阵列的更多详细信息,请参阅NumPy内部文档。

    因为numpy.reshape只是创建了一个新视图,所以您不应该害怕在必要时使用它。当您想以不同的方式索引数组时,它是正确的工具。

    然而,在长时间的计算中,通常可以首先安排构造具有“正确”形状的数组,从而最大限度地减少重塑和转置的次数。但是如果没有看到导致重塑需求的实际背景,很难说应该改变什么。

    你问题中的例子是:

    numpy.dot(M[:,0], numpy.ones((1, R)))
    

    但这并不现实。首先,这个表达:

    M[:,0].sum()
    

    更简单地计算结果。第二,0列真的有什么特别之处吗?也许你真正需要的是:

    M.sum(axis=0)
    
     类似资料:
    • 问题内容: 进入时,某些操作会恢复原状,但有些会返回(R,)。由于需要显式运算,因此这会使矩阵乘法变得更加乏味。例如,给定一个矩阵M,如果我们想在, 哪里做R行数(当然,同样的问题也会逐列出现)。我们会得到错误,因为是在外形,但在形状(1, R)。 所以我的问题是: 什么形状之间的差异(R, 1)和(R,)。我从字面上知道是数字列表和列表列表,其中所有列表仅包含一个数字。只是想知道为什么不设计使其

    • 问题内容: 和回车符(“ \ r”)有什么区别?最好使用哪一个? 问题答案: 假设您的意思是: 与环境无关的不是。 因此,它将在Windows上但在另一个环境上给您。 但是,您不应该在JTextArea中使用它,而println仅在Windows上可以正常工作。 立即编辑,因为我已经看到了代码和您的评论 根据您的情况。我认为您应该使用自己的常量-

    • 我有一个形状文件,上传路径如下: https://drive.google.com/open?id=0B1ITb_7lHh1EUFVfVWc4ekRfSnc 我使用“shapefiles”包中的“read.shapefiles”函数导入了数据: 我现在需要提取landuse对象中所有形状的横向/纵向质心,并将其添加到landuse$dbf数据框中 我尝试了两件事: 两者都给了我以下错误: 我不知道

    • 问题内容: 很快就有两个相等运算符:double equals( )和Triple equals( ),两者之间有什么区别? 问题答案: 简而言之: 操作员检查其实例值是否相等, 操作员检查引用是否指向同一实例, 长答案: 类是引用类型,可能有多个常量和变量在幕后引用类的同一单个实例。类引用保留在运行时堆栈(RTS)中,其实例保留在内存的堆区域中。当您控制平等时, 这意味着它们的实例是否彼此相等。

    • 两者的区别是什么 和 ? 第一个语句的输出是 [0 0…n次] 而第二个是 ([0] [0] .... n行)

    • ,和? 为什么只获得二次权的复杂根?我应该把它专门用于我的平方根吗?他们在背景中有什么不同?