当前位置: 首页 > 面试题库 >

Python-numpy.array形状(R,1)和(R,)之间的区别

秦胡媚
2023-03-14
问题内容

进入时numpy,某些操作会恢复原状,(R, 1)但有些会返回(R,)。由于reshape需要显式运算,因此这会使矩阵乘法变得更加乏味。例如,给定一个矩阵M,如果我们想在numpy.dot(M[:,0], numpy.ones((1, R)))哪里做R行数(当然,同样的问题也会逐列出现)。我们会得到matrices are not aligned错误,因为M[:,0]是在外形(R,),但numpy.ones((1, R))在形状(1, R)。

所以我的问题是:

  1. 什么形状之间的差异(R, 1)和(R,)。我从字面上知道是数字列表和列表列表,其中所有列表仅包含一个数字。只是想知道为什么不设计numpy使其偏向于形状(R, 1)而不是(R,)更容易进行矩阵乘法。
  2. 以上示例是否有更好的方法?无需像这样显式重塑:numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))

问题答案:
  1. NumPy中形状的含义
    你写道:“我从字面上知道这是一个数字列表和一个列表列表,其中所有列表都只包含一个数字”,但这是一种无益的思考方式。

考虑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到11的单个索引建立索引。从概念上讲,如果我们标记该单个索引i,则数组a如下所示:

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到2和0到3进行索引。如果我们标记两个索引i和j,则数组b如下所示:

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

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

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

数组d由两个索引索引,第一个索引从0到11,第二个索引始终为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

长度为1的尺寸是“自由的”(在某种意义上),因此没有什么可以阻止你进入城镇:

>>> 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内部文档。

2.怎么办?
由于numpy.reshape只是创建了一个新视图,因此不必在必要时使用它。当你想以其他方式为数组建立索引时,它是正确的工具。

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

你问题中的示例是:

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

但这是不现实的。首先,此表达式:

M[:,0].sum()

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

M.sum(axis=0)


 类似资料:
  • 在中,有些操作以的形式返回,但有些操作返回。这将使矩阵乘法更加繁琐,因为需要显式

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

  • 问题内容: 在内置的蟒蛇开放的功能,是个什么模式之间准确的区别? 特别是,文档暗示所有这些都将允许写入文件,并表示它打开文件专门用于“,但未定义这些术语的含义。 问题答案: 打开模式与标准库功能完全相同。 手册页对它们的定义如下:

  • 问题内容: 和Python和有什么不一样? 我尝试环顾四周,但没有在这些线上找到具体问题。如果已经回答,则链接就足够了。 问题答案: 0和1是退出代码。 意味着干净出口,没有任何错误/问题 表示存在一些问题/错误/问题,这就是程序退出的原因。 这不是特定于Python的,非常普遍。非零退出代码被视为异常退出,有时,错误代码指示问题所在。错误代码为零表示成功退出。 这对于其他程序,shell,调用方

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

  • 问题内容: 在mdn 与…相同 。 但是,实际上它在浏览器中有不同的显示。 您可以通过更改CSS中的注释在jsFiddle中进行尝试。 当我使用元素时,其类名将是,但使用时不会发生。 我不明白为什么。寻求帮助。非常感谢。 问题答案: 该 属性是设置的简写: 该规则应对此进行计算: 这些值在规范中定义。参见7.1.1节。的基本价值 我之所以说 “应该计算” ,是因为在IE11和可能的其他浏览器中,度