Can you please help understand what are the main differences (if any) between the native int type and the numpy.int32 or numpy.int64 types?
Another way to look at the differences is to ask what methods do the 2 kinds of objects have.
In Ipython I can use tab complete to look at methods:
In [1277]: x=123; y=np.int32(123)
int methods and attributes:
In [1278]: x.
x.bit_length x.denominator x.imag x.numerator x.to_bytes
x.conjugate x.from_bytes x.real
int 'operators'
In [1278]: x.__
x.__abs__ x.__init__ x.__rlshift__
x.__add__ x.__int__ x.__rmod__
x.__and__ x.__invert__ x.__rmul__
x.__bool__ x.__le__ x.__ror__
...
x.__gt__ x.__reduce_ex__ x.__xor__
x.__hash__ x.__repr__
x.__index__ x.__rfloordiv__
np.int32 methods and attributes (or properties). Some of the same, but a lot more, basically all the ndarray ones:
In [1278]: y.
y.T y.denominator y.ndim y.size
y.all y.diagonal y.newbyteorder y.sort
y.any y.dtype y.nonzero y.squeeze
...
y.cumsum y.min y.setflags
y.data y.nbytes y.shape
the y.__ methods look a lot like the int ones. They can do the same math.
In [1278]: y.__
y.__abs__ y.__getitem__ y.__reduce_ex__
y.__add__ y.__gt__ y.__repr__
...
y.__format__ y.__rand__ y.__subclasshook__
y.__ge__ y.__rdivmod__ y.__truediv__
y.__getattribute__ y.__reduce__ y.__xor__
y is in many ways the same as a 0d array. Not identical, but close.
In [1281]: z=np.array(123,dtype=np.int32)
np.int32 is what I get when I index an array of that type:
In [1300]: A=np.array([0,123,3])
In [1301]: A[1]
Out[1301]: 123
In [1302]: type(A[1])
Out[1302]: numpy.int32
I have to use item to remove all of the numpy wrapping.
In [1303]: type(A[1].item())
Out[1303]: int
As a numpy user, an np.int32 is an int with a numpy wrapper. Or conversely a single element of an ndarray. Usually I don't pay attention as to whether A[0] is giving me the 'native' int or the numpy equivalent. In contrast to some new users, I rarely use np.int32(123); I would use np.array(123) instead.
A = np.array([1,123,0], np.int32)
does not contain 3 np.int32 objects. Rather its data buffer is 3*4=12 bytes long. It's the array overhead that interprets it as 3 ints in a 1d. And view shows me the same databuffer with different interpretations:
In [1307]: A.view(np.int16)
Out[1307]: array([ 1, 0, 123, 0, 0, 0], dtype=int16)
In [1310]: A.view('S4')
Out[1310]: array([b'\x01', b'{', b''], dtype='|S4')
It's only when I index a single element that I get a np.int32 object.
The list L=[1, 123, 0] is different; it's a list of pointers - pointers to int objects else where in memory. Similarly for a dtype=object array.