理解numpy数组在内存中的排列方式
我正在尝试在Python中使用numpy构建OpenGL纹理,但遇到了一些问题,因为我无法预测numpy数组在内存中的组织方式。下面的示例程序(可以直接运行)展示了我的困惑:
from pylab import *
array_by_hand = array(
[[[1, 2, 3, 4], [1, 2, 3, 4]],
[[1, 2, 3, 4], [1, 2, 3, 4]]], dtype='uint8')
layers = 1 * ones((2, 2)), 2 * ones((2, 2)), 3 * ones((2, 2)), 4 * ones((2, 2))
array_from_layers = dstack(layers)
array_from_layers = array_from_layers.astype('uint8')
print array_by_hand; print
print array_from_layers; print
print ' '.join(x.encode('hex') for x in array_by_hand.data)
print ' '.join(x.encode('hex') for x in array_from_layers.data)
print
print all(array_by_hand == array_from_layers) # True
print str(array_by_hand.data) == str(array_from_layers.data) # False
虽然这两个数组在Python看来是相同的,但它们在内存中的布局却不同,因此在OpenGL中显示的效果也不同。有人能解释一下为什么会这样吗?我该如何让这两个数组的格式一致呢?
1 个回答
4
如果你调用tostring方法,它会把数组转换成C语言连续存储的格式:
>>> array_by_hand.tostring() == array_from_layers.tostring()
True
你遇到的字符串不同的原因是因为调用了dstack
。这个方法试图聪明地把多个数组叠加在一起,它的做法是简单地把源数组的底层数据合并,然后修改numpy的步幅信息。这样一来,数组就不是C语言连续存储的格式了。