Python 为什么numpy.ravel会返回副本?

Python 为什么numpy.ravel会返回副本?,python,numpy,Python,Numpy,在以下示例中: >>> import numpy as np >>> a = np.arange(10) >>> b = a[:,np.newaxis] >>> c = b.ravel() >>> np.may_share_memory(a,c) False 为什么numpy.ravel返回我的数组的副本?它不应该只是返回a 编辑: 我刚刚发现np.squese不会返回副本 >>> b

在以下示例中:

>>> import numpy as np
>>> a = np.arange(10)
>>> b = a[:,np.newaxis]
>>> c = b.ravel()
>>> np.may_share_memory(a,c)
False
为什么
numpy.ravel
返回我的数组的副本?它不应该只是返回
a

编辑:

我刚刚发现
np.squese
不会返回副本

>>> b = a[:,np.newaxis]
>>> c = b.squeeze()
>>> np.may_share_memory(a,c)
True
在这种情况下,
挤压
拉威尔
之间为什么有区别

编辑:

正如mgilson所指出的,
newaxis
将数组标记为不连续,这就是
ravel
返回副本的原因

因此,新的问题是为什么
newaxis
将数组标记为不连续的

然而,这个故事变得更加奇怪:

>>> a = np.arange(10)
>>> b = np.expand_dims(a,axis=1)
>>> b.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> c = b.ravel()
>>> np.may_share_memory(a,c)
True

根据
expand_dims
的文档,它应该相当于
newaxis

这可能不是您问题的最佳答案,但插入newaxis似乎会导致numpy将阵列视为非连续阵列--可能是出于广播目的:

>>> a=np.arange(10)
>>> b=a[:,None]
>>> a.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> b.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
但是,重塑不会导致:

>>> c=a.reshape(10,1) 
>>> c.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
这些阵列共享相同的内存:

>>> np.may_share_memory(c.ravel(),a)
True
编辑

np.expand\u dims
实际上是使用
重塑
实现的,这就是它工作的原因(我想这是文档中的一个小错误)。以下是源代码(不含docstring):

def expand_dims(a,轴):
a=a阵列(a)
形状
如果轴<0:
轴=轴+透镜(形状)+1
返回a.重塑(形状[:轴]+(1,)+形状[轴:)

看起来可能与步幅有关:

>>> c = np.expand_dims(a, axis=1)
>>> c.strides
(8, 8)

>>> b = a[:, None]
>>> b.strides
(8, 0)
>>> b.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> b.strides = (8, 8)
>>> b.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

我不确定维度1上的跨步在这里会有什么不同,但这似乎正是numpy将数组视为不连续的原因。

根据文档,必要时会复制一份副本-也许重塑意味着numpy决定有必要…这是可能的(可能的)该numpy内部可能有代码来处理奇怪的跨步(优化广播或访问速度),而
ravel
将撤销所有这些操作以将其展平,其中as
squence
可能只是敲出维度=1的维度。是的,我正要发布同样的内容。奇怪吧?我真的很好奇引擎盖下到底发生了什么。@senderle——我猜这是为了广播的缘故。但我也很好奇,很有趣!查看我对该问题的更新。我希望我们能请一位numpy开发人员来解释这一点。@user545424——在引擎盖下,
np.expand\u dims
使用
重塑
。(它构造了一组维度,在中间插入了<代码>(1)。因此,文档稍微有点错误;^)尽管用NeWxIS和切片创建一个元组是很容易的……使行为正确。
>>> c = np.expand_dims(a, axis=1)
>>> c.strides
(8, 8)

>>> b = a[:, None]
>>> b.strides
(8, 0)
>>> b.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> b.strides = (8, 8)
>>> b.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False