假设我有一个函数要求NumPy ndarray
有2个轴,例如行和列的数据矩阵。如果从这样的数组中切出“列”,则此函数也应该起作用,因此为方便起见,它应该执行一些内部X[:, np.newaxis]
。但是,我不想为此创建一个新的数组对象,因为在某些情况下这可能很昂贵。
我想知道是否有一个好方法。例如,以下代码是否安全(我的意思是,全局数组总是是否会像Python list
那样保持不变)?
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数组,但是,我找不到一个关于此的好资源。有任何想法吗?
答案 0 :(得分:5)
它不应该创建副本。例如:
>>> 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]]
)进行索引,否则它不会创建副本。几乎所有其他东西都返回一个没有副本的视图。
答案 1 :(得分:1)
它不应该创建副本 - 这些类型的操作都只是视图 - 具有更改的ndarray元数据的副本,而不是数据。
答案 2 :(得分:0)
您可以重塑输入数组以强制它为M x N
维数组,其中M
是第一维的元素数。然后,将其切片以获得第一列并对其所有元素求和。不得重塑和切片
制作副本。
所以,你可以在没有IF语句的情况下采用这种替代方法 -
def some_func2(X):
return X.reshape(X.shape[0],-1)[:,0].sum()
要检查并确认它没有使用整形和切片创建副本,您可以像{ - 1>}那样使用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
带有True
的{{1}}值是好指标,它们是视图而非副本。