Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how numpy arrays are laid out in memory

Tags:

python

numpy

I'm trying to use build OpenGL textures in python using numpy, but I'm running into problems because I can't predict how numpy arrays will be organized in memory. The example program below (which should run as-is) illustrates my confusion:

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

Although the two arrays are equivalent as far as python is concerned, the are laid out differently in memory and therefore displayed differently by OpenGL. Can someone explain why this is happening and how I might coerce both arrays to the same format?

like image 537
Kale Kundert Avatar asked Oct 05 '22 01:10

Kale Kundert


1 Answers

If you call the tostring method instead, it converts the array to C-contiguous layout:

>>> array_by_hand.tostring() == array_from_layers.tostring()
True

The reason the string is different in your case is because of the dstack call. It tries to be smart about stacking arrays together by simply combining the underlying data of the source arrays and then changing numpy's stride information. This results in the array not being in C-contiguous layout.

like image 107
jterrace Avatar answered Oct 10 '22 04:10

jterrace