我有一个python代码如下:
import numpy as np
sizes = 2000
array1 = np.empty((sizes, sizes, sizes, 3), dtype=np.float32)
for i in range(sizes):
array1[i, :, :, 0] = 1.5*i
array1[:, i, :, 1] = 2.5*i
array1[:, :, i, 2] = 3.5*i
array2 = array1.reshape(sizes*sizes*sizes, 3)
#do something with array2
array3 = array2.reshape(sizes*sizes*sizes, 3)
我想优化此代码以提高内存效率,但我不知道。我可以使用" numpy.reshape"通过更有效的内存方式?
答案 0 :(得分:1)
我认为您的代码已经具有内存效率。
如果可能,np.reshape
将返回原始数组的视图。在这种情况下也是如此,因此np.reshape
已经具有内存效率。
以下是np.reshape
返回视图的方法:
import numpy as np
# Let's make array1 smaller; it won't change our conclusions
sizes = 5
array1 = np.arange(sizes*sizes*sizes*3).reshape((sizes, sizes, sizes, 3))
for i in range(sizes):
array1[i, :, :, 0] = 1.5*i
array1[:, i, :, 1] = 2.5*i
array1[:, :, i, 2] = 3.5*i
array2 = array1.reshape(sizes*sizes*sizes, 3)
请注意array2
在某个位置的值:
assert array2[0,0] == 0
更改array1
中的相应值:
array1[0,0,0,0] = 100
请注意array2
的值会发生变化。
assert array2[0,0] == 100
由于array2
的修改导致array1
发生变化,因此您可以得出结论:array2
是array1
的视图。视图共享基础数据。由于没有复制,因此重塑具有内存效率。
array2
已成形(sizes*sizes*sizes, 3)
,因此此重塑不执行任何操作。
array3 = array2.reshape(sizes*sizes*sizes, 3)
最后,下面的断言显示array3
也受到array1
修改的影响。因此,最终证明array3
也是array1
的观点。
assert array3[0,0] == 100
答案 1 :(得分:0)
所以你的问题实际上取决于你在使用数组做什么。您当前正在存储大量冗余信息。您可以保留当前存储信息的0.15%而不会丢失任何内容。
例如,如果我们定义以下三个一维数组
a = np.linspace(0,(size-1)*1.5,size).astype(np.float32)
b = np.linspace(0,(size-1)*2.5,size).astype(np.float32)
c = np.linspace(0,(size-1)*3.5,size).astype(np.float32)
我们可以在array1
中创建任何次要条目(即最快旋转轴中的条目):
In [235]: array1[4][3][19] == np.array([a[4],b[3],c[19]])
Out[235]: array([ True, True, True], dtype=bool)
使用这一切都取决于您对数组的处理方式,因为从array1
,a
和b
重新生成c
的效率会降低。但是,如果您接近机器可以处理的极限,则牺牲性能以提高内存效率可能是必要的一步。同时移动a
,b
和c
的开销也远远低于移动array1
。