Using dtype as documented in:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html
Subdivide int16 into 2 int8‘s, called x and y. 0 and 1 are the offsets in bytes:
np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)}))
dtype(('<i2', [('x', '|i1'), ('y', '|i1')]))
Or adapted to your case:
In [30]: x=np.arange(12,dtype=np.int32)*1000
In [39]: dt=np.dtype((np.int32, {'f0':(np.uint8,0),'f1':(np.uint8,1),'f2':(np.uint8,2), 'f3':(np.uint8,3)}))
In [40]: x1=x.view(dtype=dt)
In [41]: x1['f0']
Out[41]: array([ 0, 232, 208, 184, 160, 136, 112, 88, 64, 40, 16, 248], dtype=uint8)
In [42]: x1['f1']
Out[42]: array([ 0, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 42], dtype=uint8)
compare
In [38]: x%256
Out[38]: array([ 0, 232, 208, 184, 160, 136, 112, 88, 64, 40, 16, 248])
More documentation on http://docs.scipy.org/doc/numpy/user/basics.rec.html
2) Tuple argument: The only relevant tuple case that applies to record structures is when a structure is mapped to an existing data type. This is done by pairing in a tuple, the existing data type with a matching dtype definition (using any of the variants being described here). As an example (using a definition using a list, so see 3) for further details):
x = np.zeros(3, dtype=('i4',[('r','u1'), ('g','u1'), ('b','u1'), ('a','u1')]))
array([0, 0, 0])
x['r'] # array([0, 0, 0], dtype=uint8)
In this case, an array is produced that looks and acts like a simple int32 array, but also has definitions for fields that use only one byte of the int32 (a bit like Fortran equivalencing).
One way to get a 2d array of the 4 bytes is:
In [46]: np.array([x1['f0'],x1['f1'],x1['f2'],x1['f3']])
Out[46]:
array([[ 0, 232, 208, 184, 160, 136, 112, 88, 64, 40, 16, 248],
[ 0, 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 42],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
Same idea, but more compact:
In [50]: dt1=np.dtype(('i4', [('bytes','u1',4)]))
In [53]: x2=x.view(dtype=dt1)
In [54]: x2.dtype
Out[54]: dtype([('bytes', 'u1', (4,))])
In [55]: x2['bytes']
Out[55]:
array([[ 0, 0, 0, 0],
[232, 3, 0, 0],
[208, 7, 0, 0],
[184, 11, 0, 0],
[160, 15, 0, 0],
[136, 19, 0, 0],
[112, 23, 0, 0],
[ 88, 27, 0, 0],
[ 64, 31, 0, 0],
[ 40, 35, 0, 0],
[ 16, 39, 0, 0],
[248, 42, 0, 0]], dtype=uint8)
In [56]: x2
Out[56]:
array([ 0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000,
9000, 10000, 11000])
dtypeallows you to view an array in 2 different ways. There's an example on docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html of doing this.np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)}))xis the array, you can usey = x.view(np.uint8).reshape(x.shape + (4,)).1 -> [1, 0, 0, 0]), so a[:, ::-1]may be needed after reshaping the view. But yes, that one-liner is definitely the way to go about this.