我有一个巨大的numpy.ndarray
图像array1
,当加载到RAM上时需要60GB。我需要删除该数组的最后n
个元素。一个简单的解决方案是:
array1 = array1[:n-1]
但是当我这样做时,我没有在RAM中获得任何空间,为什么呢? 如何删除这些元素,我如何在RAM中获得可用空间?我最初是为了那个收获而去除的。
答案 0 :(得分:1)
array1[:n-1]
是一个视图,一个与原始array1
共享数据缓冲区的新数组。即使重新分配array1
,也不会调整其数据缓冲区的大小。
array1.resize(n-1)
- 文档表明数据缓冲区已调整大小/重新分配,前提是该缓冲区未与其他任何内容共享。
In [1105]: arr=np.arange(1000)
In [1106]: arr.nbytes
Out[1106]: 4000
In [1107]: sys.getsizeof(arr) # those bytes plus overhead
Out[1107]: 4048
In [1108]: arr = arr[:500] # your slice
In [1109]: arr.nbytes # fewer bytes
Out[1109]: 2000
In [1110]: sys.getsizeof(arr) # just the overhead
Out[1110]: 48
sys.getsizeof
获取视图的大小,但由于它与原始arr
共享缓冲区,因此我们只能看到'开销'。原始arr
仍然存在,但无法通过名称访问。
In [1111]: arr=np.arange(1000)
In [1112]: arr.resize(500)
In [1113]: arr.nbytes
Out[1113]: 2000
In [1114]: sys.getsizeof(arr)
Out[1114]: 2048
使用resize
方法,似乎数据缓冲区已调整大小,释放了一半。但我不确定这是一种很好的测试方法,至少不适用于像这样的小型数组。
我们可能有3个系统管理内存 - numpy,python解释器和系统。我们必须进一步深入研究代码(可能是C-api),以确定在resize
之后是否将内存添加到某种numpy
缓存中,或者是通过Python垃圾收集器或返回系统。
============
resize
后跟一个新的shape
似乎会缩小第一个轴的大小:
In [1120]: arr = np.arange(100).reshape(10,10).copy()
In [1121]: arr.resize(50)
In [1122]: sys.getsizeof(arr)
Out[1122]: 248
In [1123]: arr = np.arange(100).reshape(10,10).copy()
In [1124]: sys.getsizeof(arr)
Out[1124]: 456
In [1125]: arr.resize(50)
In [1126]: sys.getsizeof(arr)
Out[1126]: 248
In [1127]: arr.shape
Out[1127]: (50,)
In [1128]: arr.shape=(5,10) # inplace reshape
In [1129]: arr
Out[1129]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]])