在不创建昂贵副本的情况下引用 numpy 数组

Referencing a numpy arrray without creating an expensive copy

假设我有一个函数需要 NumPy ndarray 有 2 个轴,例如,行和列的数据矩阵。如果从这样的数组中切出 "column",此函数也应该有效,因此为了方便起见,它应该做一些内部 X[:, np.newaxis]。但是,我不想为此创建一个新的数组对象,因为在某些情况下这可能很昂贵。

请问有没有好的方法。例如,下面的代码是否安全(我的意思是,全局数组 always 是否会像 Python lists 那样保持不变)?

X1 = np.array([[1,2,3], [4,5,6], [7,8,9]])
X2 = np.array([1,4,7])

def some_func(X):
    if len(X.shape) == 1:
        X = X[:, np.newaxis]
    return X[:,0].sum()       

some_func(X2)
some_func(X1[:, 0])
some_func(X1)

我问这个问题是因为我听说在某些情况下有时会复制 NumPy 数组,但是,我找不到这方面的好资源。有任何想法吗?

它不应该创建副本。举例说明:

>>> A = np.ones((50000000,))
>>> B = A[:,np.newaxis]
>>> B.flags
  C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False

注意 OWNDATA : False - 它正在与 A 共享数据。

有关更多详细信息,请查看 http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html。基本规则是它不会创建副本,除非您使用索引数组(例如 A[[1,2,4]])或布尔数组(例如 A[[True, False, True]])进行索引。几乎所有其他内容 returns 没有副本的视图。

它不应该创建一个副本 - 这些类型的操作都只是视图 - 一个具有更改的 ndarray 元数据但不是数据的副本。

您可以重塑输入数组以强制其成为 M x N 维数组,其中 M 是第一维的元素数。然后,将其切片以获得第一列并对所有元素求和。重塑和切片不得 制作副本。

因此,您可以采用这种没有 IF 语句的替代方法 -

def some_func2(X):
    return X.reshape(X.shape[0],-1)[:,0].sum()

要检查并确认它不会创建带有整形和切片的副本,您可以像这样使用 np.may_share_memory -

In [515]: X1
Out[515]: 
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [516]: np.may_share_memory(X1,X1.reshape(X1.shape[0],-1)[:,0])
Out[516]: True

In [517]: X2
Out[517]: array([1, 4, 7])

In [518]: np.may_share_memory(X2,X2.reshape(X2.shape[0],-1)[:,0])
Out[518]: True

具有 np.may_share_memoryTrue 值是 表明它们是视图而不是副本。