There are several major differences. The first is that python integers are flexible-sized (at least in python 3.x). This means they can grow to accommodate any number of any size (within memory constraints, of course). The numpy integers, on the other hand, are fixed-sized. This means there is a maximum value they can hold. This is defined by the number of bytes in the integer (int32 vs. int64), with more bytes holding larger numbers, as well as whether the number is signed or unsigned (int32 vs. uint32), with unsigned being able to hold larger numbers but not able to hold negative number.

So, you might ask, why use the fixed-sized integers? The reason is that modern processors have built-in tools for doing math on fixed-size integers, so calculations on those are much, much, much faster. In fact, python uses fixed-sized integers behind-the-scenes when the number is small enough, only switching to the slower, flexible-sized integers when the number gets too large.

Another advantage of fixed-sized values is that they can be placed into consistently-sized adjacent memory blocks of the same type. This is the format that numpy arrays use to store data. The libraries that numpy relies on are able to do extremely fast computations on data in this format, in fact modern CPUs have built-in features for accelerating this sort of computation. With the variable-sized python integers, this sort of computation is impossible because there is no way to say how big the blocks should be and no consistentcy in the data format.

That being said, numpy is actually able to make arrays of python integers. But rather than arrays containing the values, instead they are arrays containing references to other pieces of memory holding the actual python integers. This cannot be accelerated in the same way, so even if all the python integers fit within the fixed integer size, it still won't be accelerated.

None of this is the case with Python 2. In Python 2, Python integers are fixed integers and thus can be directly translated into numpy integers. For variable-length integers, Python 2 had the long type. But this was confusing and it was decided this confusion wasn't worth the performance gains, especially when people who need performance would be using numpy or something like it anyway.

Answer from TheBlackCat on Stack Overflow
Top answer
1 of 3
62

There are several major differences. The first is that python integers are flexible-sized (at least in python 3.x). This means they can grow to accommodate any number of any size (within memory constraints, of course). The numpy integers, on the other hand, are fixed-sized. This means there is a maximum value they can hold. This is defined by the number of bytes in the integer (int32 vs. int64), with more bytes holding larger numbers, as well as whether the number is signed or unsigned (int32 vs. uint32), with unsigned being able to hold larger numbers but not able to hold negative number.

So, you might ask, why use the fixed-sized integers? The reason is that modern processors have built-in tools for doing math on fixed-size integers, so calculations on those are much, much, much faster. In fact, python uses fixed-sized integers behind-the-scenes when the number is small enough, only switching to the slower, flexible-sized integers when the number gets too large.

Another advantage of fixed-sized values is that they can be placed into consistently-sized adjacent memory blocks of the same type. This is the format that numpy arrays use to store data. The libraries that numpy relies on are able to do extremely fast computations on data in this format, in fact modern CPUs have built-in features for accelerating this sort of computation. With the variable-sized python integers, this sort of computation is impossible because there is no way to say how big the blocks should be and no consistentcy in the data format.

That being said, numpy is actually able to make arrays of python integers. But rather than arrays containing the values, instead they are arrays containing references to other pieces of memory holding the actual python integers. This cannot be accelerated in the same way, so even if all the python integers fit within the fixed integer size, it still won't be accelerated.

None of this is the case with Python 2. In Python 2, Python integers are fixed integers and thus can be directly translated into numpy integers. For variable-length integers, Python 2 had the long type. But this was confusing and it was decided this confusion wasn't worth the performance gains, especially when people who need performance would be using numpy or something like it anyway.

2 of 3
36

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.<tab>
x.bit_length   x.denominator  x.imag         x.numerator    x.to_bytes
x.conjugate    x.from_bytes   x.real         

int 'operators'

In [1278]: x.__<tab>
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.<tab>
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.__<tab>
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.

🌐
NumPy
numpy.org › doc › stable › user › basics.types.html
Data types — NumPy v2.4 Manual
NumPy knows that int refers to numpy.int_, bool means numpy.bool, that float is numpy.float64 and complex is numpy.complex128. The other data-types do not have Python equivalents. Sometimes the conversion can overflow, for instance when converting a numpy.int64 value 300 to numpy.int8.
Discussions

dtype(int) is int64 not python int
np.dtype(int) is int64, not python int as expected. >>> import numpy as np >>> a = np.array([2],dtype = np.dtype(int)) >>> a.dtype dtype('int64') >>> a**... More on github.com
🌐 github.com
5
November 3, 2018
numpy.int64 is not instance of int
Looks like numpy has done the work to make its int32 and float64 recognisable by other software but not int64. More on github.com
🌐 github.com
5
January 27, 2013
Preventing numpy from converting float type to numpy.int64 type
Numpy arrays have a defined data ... of dtype int64, because that's how you initialized it in the first place: as the docs say, if no type is given explicitly then "the type will be determined as the minimum type required to hold the objects in the sequence". So the solution is to explicitly make it an array of floats: eta_hat = numpy.array( [ [0], [0], [0] ], dtype=float) ... You can use the transpose of a row vector. ... I would like to learn NumPy but don't know if I need to. ... Are int (built-in ... More on reddit.com
🌐 r/learnpython
3
1
April 3, 2023
How to convert python int into numpy.int64? - Stack Overflow
Given a variable in python of type int, e.g. z = 50 type(z) ## outputs is there a straightforward way to convert this variable into numpy.int64? It appears one would have to More on stackoverflow.com
🌐 stackoverflow.com
🌐
Codegive
codegive.com › blog › numpy_int64_vs_int.php
Numpy int64 vs int
It provides an ndarray object (N-dimensional array) that stores homogenous data, meaning all elements in the array are of the same type. To achieve this efficiency, NumPy defines its own fixed-size data types, including integers. Fixed Size: numpy.int64 is a 64-bit signed integer.
🌐
GitHub
github.com › numpy › numpy › issues › 12322
dtype(int) is int64 not python int · Issue #12322 · numpy/numpy
November 3, 2018 - np.dtype(int) is int64, not python int as expected. >>> import numpy as np >>> a = np.array([2],dtype = np.dtype(int)) >>> a.dtype dtype('int64') >>> a**63 array([-9223372036854775808]) >>> np.version.version '1.14.3' np.dtype(int) is expected ...
Author   ra1u
🌐
GitHub
github.com › numpy › numpy › issues › 2951
numpy.int64 is not instance of int · Issue #2951 · numpy/numpy
January 27, 2013 - Looks like numpy has done the work to make its int32 and float64 recognisable by other software but not int64.
Author   pasunboneleve
🌐
Reddit
reddit.com › r/learnpython › preventing numpy from converting float type to numpy.int64 type
r/learnpython on Reddit: Preventing numpy from converting float type to numpy.int64 type
April 3, 2023 - Numpy arrays have a defined data ... of dtype int64, because that's how you initialized it in the first place: as the docs say, if no type is given explicitly then "the type will be determined as the minimum type required to hold the objects in the sequence". So the solution is to explicitly make it an array of floats: eta_hat = numpy.array( [ [0], [0], [0] ], dtype=float) ... You can use the transpose of a row vector. ... I would like to learn NumPy but don't know if I need to. ... Are int (built-in ...
🌐
Python Data Science Handbook
jakevdp.github.io › PythonDataScienceHandbook › 02.01-understanding-data-types.html
Understanding Data Types in Python | Python Data Science Handbook
The difference between a dynamic-type ... (NumPy-style) array is illustrated in the following figure: At the implementation level, the array essentially contains a single pointer to one contiguous block of data. The Python list, on the other hand, contains a pointer to a block of pointers, each of which in turn points to a full Python object like the Python integer we saw ...
Find elsewhere
🌐
Runebook.dev
runebook.dev › en › docs › numpy › reference › arrays.scalars › numpy.intp
Why You Should Use numpy.int64 Instead of intp
In this case, NumPy will usually "upcast" the result to the larger or more "general" type, which might be numpy.int64. This is usually okay, but it's important to be aware of. ... To ensure predictable behavior, it's a good practice to explicitly ...
🌐
NumPy
numpy.org › doc › 1.22 › user › basics.types.html
Data types — NumPy v1.22 Manual
>>> np.iinfo(int) # Bounds of the default integer on this system. iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64) >>> np.iinfo(np.int32) # Bounds of a 32-bit integer iinfo(min=-2147483648, max=2147483647, dtype=int32) >>> np.iinfo(np.int64) # Bounds of a 64-bit integer iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)
🌐
Medium
medium.com › @pritioli › essential-numpy-data-types-a-must-know-guide-ad3657f708b7
Essential NumPy Data Types: A Must-Know Guide | by Code & Cognition | Medium
December 22, 2023 - On most modern systems, the default data type for integers in NumPy is int64 )is converted to float64 when specifying float (Python’s default floating-point numbers are typically 64-bit).
🌐
Google Groups
groups.google.com › g › numpy › c › 6nCcuw3NkKw
[Numpy-discussion] PyInt and Numpy's int64 conversion
I want to convert a numpy array of integers (whose elements are numpy's 'int64') The problem is that it this int64 type is not compatible with the standard python integer type: I cannot use PyInt_Check, and PyInt_AsUnsignedLongMask to check and convert from int64: basically PyInt_Check returns ...
🌐
HackMD
hackmd.io › @mattip › rk5K-f4-2
NumPy2 lighning talk: Change `np.int`_ to `np.int64` on all platforms - HackMD
April 3, 2023 - The relevant issues discussing ...l#default-data-types): > The default integer data type should be the same across platforms, but the default may vary depending on whether Python is 32-bit or 64-bit....
🌐
Saturn Cloud
saturncloud.io › blog › converting-python-int-to-numpyint64-a-comprehensive-guide
Converting Python int to numpy.int64: A Guide | Saturn Cloud Blog
October 4, 2023 - However, this flexibility comes at the cost of memory and speed. On the other hand, numpy.int64 is a fixed-size integer type that can store integers from -9223372036854775808 to 9223372036854775807.
🌐
GitHub
github.com › h5py › h5py › issues › 2456
With numpy 2 (and h5py 3.11) all integers get written as np.int64 and it breaks things. · Issue #2456 · h5py/h5py
July 10, 2024 - Since numpy v2 (and h5py 3.11) if I do: a = 1 with h5py.File('tmp.h5', 'w') as fl: fl.attrs['a'] = a with h5py.File('tmp.h5', 'r') as fl: new_a = fl.attrs['a'] Then new_a has type np.int64 rather than int. This is fine for some purposes, i.e. I can do a == new_a and it returns a truthy value (np.True_ now instead of True).
Author   steven-murray
🌐
SciPy
docs.scipy.org › doc › › numpy-1.10.1 › user › basics.types.html
Data types — NumPy v1.10 Manual
October 18, 2015 - Numpy supports a much greater variety of numerical types than Python does. This section shows which are available, and how to modify an array’s data-type. Additionally to intc the platform dependent C integer types short, long, longlong and their unsigned versions are defined.