我需要在我的项目中处理一些大的numpy
数组。从磁盘加载这样一个数组之后,我的计算机的内存将消耗掉一半以上。你知道吗
在数组加载之后,我对它做了几个切片(几乎一半的数组都会被选中),然后我收到错误消息,告诉我内存不足。你知道吗
通过做一个我理解的小实验,我收到了错误,因为当numpy
数组被切片时,将创建一个副本
import numpy as np
tmp = np.linspace(1, 100, 100)
inds = list(range(100))
tmp_slice = tmp[inds]
assert id(tmp) == id(tmp_slice)
返回AssertionError
有没有办法使numpy
数组的片只引用原始数组的内存地址,这样就不会复制数据项?你知道吗
在Python中,
slice
是一个定义良好的类,具有start
、stop
、step
值。当我们用alist[1: 10: 2]
索引列表时使用它。这将生成一个新列表,其中包含原始指针的副本。在numpy
中,它们用于basic indexing
,例如arr[:3, -3:]
。这将创建原始的view
。view
共享数据缓冲区,但有自己的shape
和strides
。你知道吗但是当我们用列表、数组或布尔数组(mask)索引数组时,它必须创建一个副本,一个有自己数据缓冲区的数组。元素的选择太复杂或不规则,无法用
shape
和strides
属性来表示。你知道吗在某些情况下,索引数组很小(与原始数组相比),副本也很小。但是如果我们排列整个数组,那么索引数组和副本都将和原始数组一样大。你知道吗
通过阅读this、this和this我认为你的问题在于使用高级切片,重申其中一个答案numpy docs清楚地表明
因此,与其这样做:
您应该使用:
这将导致view rather than a copy。您可以通过尝试以下方法来发现差异:
tmp[0] = 5
在第一种情况下
tmp_slice[0]
将返回1.0
,但在第二种情况下它将返回5
。你知道吗相关问题 更多 >
编程相关推荐