【问题标题】:Resize NumPy array to smaller size without copy将 NumPy 数组的大小调整为更小的大小而不进行复制
【发布时间】:2015-09-04 12:18:38
【问题描述】:

当我使用 resize 方法收缩一个 numpy 数组时(即,由于resize,数组变小了),是否保证不复制?

例子:

a = np.arange(10)            # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a.resize(5, refcheck=False)  # array([0, 1, 2, 3, 4])

据我了解,这应该始终可以在不制作副本的情况下进行。我的问题:实施是否确实保证总是如此?不幸的是,resize 的文档对此只字未提。

【问题讨论】:

  • 如果你的新尺寸总是变小,为什么不将数组切片并分配给你自己呢?
  • @EdChum:你的意思是a = a[:5]?老实说,我没有想到这个选项。不过,我不知道切片在内部是如何工作的。如果没有在某处制作数据副本,这是否可行?

标签: python arrays numpy


【解决方案1】:

numpy 数组是后台固定大小的数组,任何类型的调整大小都会复制数组。

话虽如此,您可以只使用数组的子集有效地创建数组的切片,而无需调整大小/复制。

>>> import numpy
>>> a = numpy.arange(10)
>>> b = a[:5]
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([0, 1, 2, 3, 4])
>>>
>>> a += 10
>>> a
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> b
array([10, 11, 12, 13, 14])
>>>
>>> b += 10
>>> a
array([20, 21, 22, 23, 24, 15, 16, 17, 18, 19])
>>> b
array([20, 21, 22, 23, 24])

【讨论】:

  • 谢谢,我真的不知道我可以为此使用切片。但是,这有一个警告:a 的未使用部分的内存未释放(在某些情况下这可能是一个问题)。如果我这样做del a 会发生什么?它会保留完整的数据,还是足够聪明地只保留可通过b 访问的部分?
  • 在执行del a 时,它将完全保留a,因为它仍然存在。 b 仅显示一小部分 a 但它仍然存在。真正释放内存的唯一方法是将其复制到新数组并删除旧数组。在后台 numpy 只是在创建/删除数组时执行标准 malloc/free 并且不可能在 c 中 free 数组的一部分。
  • 还有一个问题:为什么resize在缩小数组时要进行复制?我不是内存分配工作原理的专家,但难道不能只释放分配内存的最后部分并保留前部分而不复制任何内容吗?
  • 这里有一些关于后台工作的解释:stackoverflow.com/questions/2479766/…
  • @Mr.F:正确,但据我所知,仅在简单地更改数组的形状(而不是大小)时才有效。例如,将大小从 (4,1) 调整为 (2, 2)(1, 4)。不过,我应该注意,我没有太彻底地查看源代码。可以在此处找到源以进行进一步检查:github.com/numpy/numpy/…
猜你喜欢
  • 2021-10-01
  • 2013-12-27
  • 2021-04-21
  • 2015-05-06
  • 2017-01-24
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多