在以下示例中:
>>> 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.squeeze
不会返回副本。
>>> b = a[:,np.newaxis]
>>> c = b.squeeze()
>>> np.may_share_memory(a,c)
True
为什么在这种情况下squeeze
和ravel
之间存在差异?
编辑:
正如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_dims
实际上是使用reshape
实现的,这就是它工作的原因(我想这是文档中的一个小错误)。以下是来源(没有文档字符串):
def expand_dims(a,axis):
a = asarray(a)
shape = a.shape
if axis < 0:
axis = axis + len(shape) + 1
return a.reshape(shape[:axis] + (1,) + shape[axis:])
看起来可能与步幅有关:
>>> 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将数组视为不连续的原因。