There is a difference between elements of an array and the object you get when indexing one.
The array has a data buffer. It is a block of bytes the numpy manages with its own compiled code. Individual elements may be represented by 1 byte, 4, 8, 16, etc.
In [478]: A=np.array([1,2,3])
In [479]: A.__array_interface__
Out[479]:
{'data': (167487856, False),
'descr': [('', '<i4')],
'shape': (3,),
'strides': None,
'typestr': '<i4',
'version': 3}
view the data as a list of bytes (displayed as characters):
In [480]: A.view('S1')
Out[480]:
array(['\x01', '', '', '', '\x02', '', '', '', '\x03', '', '', ''],
dtype='|S1')
When you select an element of A
you get back a one element array (or something like it):
In [491]: b=A[0]
In [492]: b.shape
Out[492]: ()
In [493]: b.__array_interface__
Out[493]:
{'__ref': array(1),
'data': (167480104, False),
'descr': [('', '<i4')],
'shape': (),
'strides': None,
'typestr': '<i4',
'version': 3}
The type
is different, but b
has most of the same attributes as A
, shape
, strides
, mean
, etc.
You have to use .item
to access the underlying 'scalar':
In [496]: b.item()
Out[496]: 1
In [497]: type(b.item())
Out[497]: int
So you can think of b
as a scalar with a numpy
wrapper. The __array_interface__
for b
looks very much like that of np.array(1)
.