我试图将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数组,并且我试图评估是否应该接受图像列表作为输入,或者这是否会导致数据被复制。我不接受数据复制,因为我正在使用非常大的数据集。
答案 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数组。