[Numpy-discussion] slices of structured arrays?

josef.pktd@gmai... josef.pktd@gmai...
Tue Dec 8 23:45:32 CST 2009

```2009/12/8 Ernest Adrogué <eadrogue@gmx.net>:
> Hello,
>
> Here's a structured array with fields 'a','b' and 'c':
>
> s=[(i,int) for i in 'abc']
> t=np.zeros(1,s)
>
> It has the form: array([(0, 0, 0)]
>
> I was wondering if such an array can be accessed like an
> ordinary array (e.g., with a slice) in order to set multiple
> values at once.
>
> t[0] does not access the first element of the array, instead
> it returns the whole array.
>
> In [329]: t[0]
> Out[329]: (1, 0, 0)
>
> But this array is type np.void and does not support slices.
> t[0][0] returns the first element, but t[0][:2] fails with
> IndexError: invalid index.
>
> Any suggestion?

as long as all numbers are of the same type, you can create a view
that behaves (mostly) like a regular array

>>> t0=np.arange(12).reshape(-1,3)
>>> t0
array([[ 0,  1,  2],
[ 3,  4,  5],
[ 6,  7,  8],
[ 9, 10, 11]])
>>> t0.dtype = s
>>> t0
array([[(0, 1, 2)],
[(3, 4, 5)],
[(6, 7, 8)],
[(9, 10, 11)]],
dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])
>>> t0.view(int)
array([[ 0,  1,  2],
[ 3,  4,  5],
[ 6,  7,  8],
[ 9, 10, 11]])
>>> t0.view(int)[3]
array([ 9, 10, 11])
>>> t0.view(int)[3,1:]
array([10, 11])

structured arrays treat all parts of the dtype as a single array
element, your t[0] returns the first row/element corresponding to s

>>> t0.shape
(4, 1)

>>> t1=np.arange(12)
>>> t1.dtype = s
>>> t1
array([(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)],
dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])
>>> t1.shape
(4,)
>>> t1.view(int)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> t1.view(int).reshape(-1,3)
array([[ 0,  1,  2],
[ 3,  4,  5],
[ 6,  7,  8],
[ 9, 10, 11]])
>>> t1.view(int).reshape(-1,3)[2,2:]
array([8])
>>> t1.view(int).reshape(-1,3)[2,1:]
array([7, 8])

as long as there is no indexing that makes a copy, you can still
change the original array by changing the view

>>> t1.view(int).reshape(-1,3)[2,1:] = 0
>>> t1
array([(0, 1, 2), (3, 4, 5), (6, 0, 0), (9, 10, 11)],
dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])

If the numbers are of different types, e.g. some columns int some
float, it gets difficult.

I often need some trial and error, but there should be quite a few
examples on the mailing list.

Josef

>
> Ernest
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
```