将2D numpy数组列表转换为3D数组时的内存复制

时间:2016-12-15 08:05:49

标签: python arrays numpy

我试图将2D numpy数组列表转换为3D数组,我想知道数据是否被复制。

例如,使用此程序:

images = []
for i in range(10):
    images.append(numpy.random.rand(100, 100))
volume = numpy.array(images)

有没有办法检查volume[n]是否指的是与images[n]相同的内存块?

我需要将我的数据作为3D数组,并且我试图评估是否应该接受图像列表作为输入,或者这是否会导致数据被复制。我不接受数据复制,因为我正在使用非常大的数据集。

4 个答案:

答案 0 :(得分:2)

我可以引用一个关于列表和数组之间存储差异的问题,但要根据你的情况进行定制:

您的列表中有一个数据缓冲区,其中包含存储在内存中其他位置的数组对象的指针。 images.append只更新指针列表。列表副本只会复制指针。

数组将其所有数据存储在连续的内存缓冲区中。因此,创建volume np.array()必须将每个组件数组中的值复制到自己的缓冲区。如果使用某些版本的np.concatenate来编译3d数组,则同样适用。

numpy函数通常在开头有一个x=np.asarray(x)语句。实际上它说,“我正在使用数组,但我会让你给我一个列表”。

您可以跳过它并仅接受3d数组。但那个3d阵列是如何构建的呢?对于随机的3d数组,您可以使用一个语句:

arr = numpy.random.rand(10, 100, 100)

但如果图像是从文件中单独加载的,则某些人或某人必须执行一个或多个副本才能创建该3d图像阵列。是你还是你的用户?

我的一般建议是不要过于偏执地制作副本 - 直到你的代码运行并且你知道,从分析副本很昂贵,或者你开始遇到MemoryError问题。

答案 1 :(得分:1)

导入numpy后,Windows任务管理器说我的Python进程使用了​​14 MB。构建images(虽然使用range(5000))后,它的速度为396 MB(多382 MB)。在构建volume之后,它是778 MB(另外382 MB)。所以看起来像是复制品。在Windows 10上使用Python 3.5.2中的NumPy 1.11.1。

答案 2 :(得分:1)

numpy允许您测试两个数组是否共享内存(在这种情况下,这是一个不错的代理)

for i, img in enumerate(images):
    print(i, numpy.may_share_memory(img, volume))
# all False

这次看起来像是被复制了。

答案 3 :(得分:0)

来自numpy.array

  

copy:bool 可选

     

如果为true(默认值),则复制对象。否则,仅在List<String> typeUser = Arrays.asList("ADMIN", "USER"); ListSelect type = new ListSelect("Type", typeUser); type.setNullSelectionAllowed(false); type.setRows(2); 返回副本时才会生成副本,如果obj是嵌套序列,则为,或者如果需要副本以满足任何其他要求(dtype,order,等)。

我很确定在使用__array__测试后你有一个嵌套序列。不幸的是,确定copy=False是否返回列表(或任何其他迭代器)的副本超出了我的google-fu,但似乎很可能,因为你不能原生地迭代一个numpy数组。