Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 引用numpy arrray而不创建昂贵的副本_Python_Arrays_Numpy_Reference_Slice - Fatal编程技术网

Python 引用numpy arrray而不创建昂贵的副本

Python 引用numpy arrray而不创建昂贵的副本,python,arrays,numpy,reference,slice,Python,Arrays,Numpy,Reference,Slice,假设我有一个函数,要求NumPyndarray具有两个轴,例如,行和列的数据矩阵。如果从这样的数组中分割出一个“列”,那么这个函数也应该工作,因此为了方便起见,它应该执行一些内部X[:,np.newaxis]。但是,我不想为此创建一个新的数组对象,因为在某些情况下这可能会很昂贵 我想知道是否有一个好方法来做这件事。例如,下面的代码是否安全(我的意思是,全局数组是否总是像Pythonlists一样保持不变) 我这样问是因为我听说在某些情况下NumPy数组有时会被复制,但是,我找不到关于这方面的好资

假设我有一个函数,要求NumPy
ndarray
具有两个轴,例如,行和列的数据矩阵。如果从这样的数组中分割出一个“列”,那么这个函数也应该工作,因此为了方便起见,它应该执行一些内部
X[:,np.newaxis]
。但是,我不想为此创建一个新的数组对象,因为在某些情况下这可能会很昂贵

我想知道是否有一个好方法来做这件事。例如,下面的代码是否安全(我的意思是,全局数组是否总是像Python
list
s一样保持不变)


我这样问是因为我听说在某些情况下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共享数据


有关更多详细信息,请查看。基本规则是,除非使用索引数组(例如
a[[1,2,4]]
)或布尔数组(例如
a[[True,False,True]]
)进行索引,否则它不会创建副本。几乎所有其他内容都返回一个没有副本的视图。

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

您可以重新调整输入数组的形状,使其成为
M x N
维数组,其中
M
是第一个维度的元素数。然后,对其进行切片以获得第一列并对其所有元素求和。不得进行整形和切片 复制

因此,您可以在不使用IF语句的情况下使用这种替代方法-

def some_func2(X):
    return X.reshape(X.shape[0],-1)[:,0].sum()
要检查并确认它没有通过整形和切片创建副本,您可以使用
np。可以像这样共享内存-

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\u share\u memory
True
值很好地表明它们是视图而不是副本。

您选择
[:,np.newaxis]
的具体原因是什么?如果它是
X=X[np.newaxis]
的话,也就是说,当输入是1D数组时,它可以保持形状为2D数组
1xn
吗?对不起,我没有提到它,但我想要一个
Nx1
维数组。NumPy的美妙之处在于,与列表不同,请勿在切片操作期间复制。你会得到一个轻量级的包装。但这也意味着您可以通过更改片来影响主阵列。我几乎可以肯定,numpy的c代码中分配了一个新的连续内存块(它可能会在返回时被垃圾回收,也可能不会被垃圾回收)。。。它应该很容易用内存分析器进行验证。。。我只知道这一点,因为我只需要和它斗争一两天ago@JoranBeasley至少根据文档“基本切片生成的所有数组始终是原始数组的视图”(基本切片下列出了
np.newaxis
)。如果代码做了一些不同的事情,我很乐意被更正!我可以保证,对于一个不能分配30mb连续内存的win32应用程序,我在
a=a[:,columns]
上遇到了一个内存错误(正如我所说,它可能会在离开C区后立即被垃圾回收)但这可能不是OP的关注点,可能取决于列是什么——如果是索引列表,我想这是意料之中的。如果这是一个片段,那么它会更令人惊讶。@JoranBeasley如果你能追踪到你案件的细节,这将是一个很好的例子。它通常不需要分配任何内存,因此如果需要,我们应该尝试将其修复。谢谢,我不知道
np。可以共享内存
,并且我有一些场景,在这些场景中,这对测试非常有用。我喜欢
X.reshape(X.shape[0],-1)
而不是
if
+
X[:,np.newaxis]
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