Use val.item() to convert most NumPy values to a native Python type:

import numpy as np

# for example, numpy.float32 -> python float
val = np.float32(0)
pyval = val.item()
print(type(pyval))         # <class 'float'>

# and similar...
type(np.float64(0).item()) # <class 'float'>
type(np.uint32(0).item())  # <class 'int'>
type(np.int16(0).item())   # <class 'int'>
type(np.cfloat(0).item())  # <class 'complex'>
type(np.datetime64(0, 'D').item())  # <class 'datetime.date'>
type(np.datetime64('2001-01-01 00:00:00').item())  # <class 'datetime.datetime'>
type(np.timedelta64(0, 'D').item()) # <class 'datetime.timedelta'>
...

(A related method np.asscalar(val) was deprecated with 1.16, and removed with 1.23).


For the curious, to build a table of conversions of NumPy array scalars for your system:

for name in dir(np):
    obj = getattr(np, name)
    if hasattr(obj, 'dtype'):
        try:
            if 'time' in name:
                npn = obj(0, 'D')
            else:
                npn = obj(0)
            nat = npn.item()
            print('{0} ({1!r}) -> {2}'.format(name, npn.dtype.char, type(nat)))
        except:
            pass

There are a few NumPy types that have no native Python equivalent on some systems, including: clongdouble, clongfloat, complex192, complex256, float128, longcomplex, longdouble and longfloat. These need to be converted to their nearest NumPy equivalent before using .item().

Answer from Mike T on Stack Overflow
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ stable โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v2.4 Manual
A basic numerical type name combined with a numeric bitsize defines a concrete type. The bitsize is the number of bits that are needed to represent a single value in memory. For example, numpy.float64 is a 64 bit floating point data type. Some types, such as numpy.int_ and numpy.intp, have ...
Top answer
1 of 13
573

Use val.item() to convert most NumPy values to a native Python type:

import numpy as np

# for example, numpy.float32 -> python float
val = np.float32(0)
pyval = val.item()
print(type(pyval))         # <class 'float'>

# and similar...
type(np.float64(0).item()) # <class 'float'>
type(np.uint32(0).item())  # <class 'int'>
type(np.int16(0).item())   # <class 'int'>
type(np.cfloat(0).item())  # <class 'complex'>
type(np.datetime64(0, 'D').item())  # <class 'datetime.date'>
type(np.datetime64('2001-01-01 00:00:00').item())  # <class 'datetime.datetime'>
type(np.timedelta64(0, 'D').item()) # <class 'datetime.timedelta'>
...

(A related method np.asscalar(val) was deprecated with 1.16, and removed with 1.23).


For the curious, to build a table of conversions of NumPy array scalars for your system:

for name in dir(np):
    obj = getattr(np, name)
    if hasattr(obj, 'dtype'):
        try:
            if 'time' in name:
                npn = obj(0, 'D')
            else:
                npn = obj(0)
            nat = npn.item()
            print('{0} ({1!r}) -> {2}'.format(name, npn.dtype.char, type(nat)))
        except:
            pass

There are a few NumPy types that have no native Python equivalent on some systems, including: clongdouble, clongfloat, complex192, complex256, float128, longcomplex, longdouble and longfloat. These need to be converted to their nearest NumPy equivalent before using .item().

2 of 13
45

If you want to convert (numpy.array OR numpy scalar OR native type OR numpy.darray) TO native type you can simply do :

converted_value = getattr(value, "tolist", lambda: value)()

tolist will convert your scalar or array to python native type. The default lambda function takes care of the case where value is already native.

๐ŸŒ
w3resource
w3resource.com โ€บ python-exercises โ€บ numpy โ€บ basic โ€บ numpy-basic-exercise-41.php
NumPy: Convert numpy dtypes to native python types - w3resource
August 28, 2025 - This problem involves writing a NumPy program to convert NumPy data types (dtypes) to native Python types. The task requires using NumPy's type conversion functions to transform NumPy-specific data types, such as numpy.int32 or numpy.float32, into their equivalent native Python types, like int or float.
๐ŸŒ
Statology
statology.org โ€บ home โ€บ how to convert numpy array of floats into integers
How to Convert NumPy Array of Floats into Integers
April 3, 2025 - rounded_integer_array = (np.rint(some_floats)).astype(int) ... The following examples show how to use each method in practice with the following NumPy array of floats:
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ stable โ€บ reference โ€บ generated โ€บ numpy.ndarray.astype.html
numpy.ndarray.astype โ€” NumPy v2.4 Manual
June 22, 2021 - To avoid this, one should use a.real.astype(t). ... Try it in your browser! >>> import numpy as np >>> x = np.array([1, 2, 2.5]) >>> x array([1. , 2. , 2.5]) ... >>> x.astype(int, casting="same_value") Traceback (most recent call last): ...
๐ŸŒ
Kaggle
kaggle.com โ€บ code โ€บ phanttan โ€บ tips-convert-numpy-float-to-integer
๐ŸŒ‹[Tips]๐ŸŒป Convert Numpy Float to Integer
Checking your browser before accessing www.kaggle.com ยท Click here if you are not automatically redirected after 5 seconds
Find elsewhere
Top answer
1 of 1
12

All your problems are indeed related.

A numpy array is an array that holds objects efficiently. It does this by having these objects be of the same type, like strings (of equal length) or integers or floats. It can then easily calculate just how much space each element needs and how many bytes it must "jump" to access the next element (we call these the "strides").

When you create an array from a list, numpy will try to determine a suitable data type ("dtype") from that list, to ensure all elements can be represented well. Only when you specify the dtype explicitly, will it not make an educated guess.

Consider the following example:

>>> import numpy as np
>>> integer_array = np.array([1,2,3])  # pass in a list of integers
>>> integer_array
array([1, 2, 3])
>>> integer_array.dtype
dtype('int64')

As you can see, on my system it returns a data type of int64, which is a representation of integers using 8 bytes. It chooses this, because:

  1. numpy recognizes all elements of the list are integers
  2. my system is a 64-bit system

Now consider an attempt at changing that array:

>>> integer_array[0] = 2.4  # attempt to put a float in an array with dtype int
>>> integer_array # it is automatically converted to an int!
array([2, 2, 3])

As you can see, once a datatype for an array was set, automatic casting to that datatype is done. Let's now consider what happens when you pass in a list that has at least one float:

>>> float_array = np.array([1., 2,3])
>>> float_array
array([ 1.,  2.,  3.])
>>> float_array.dtype
dtype('float64')

Once again, numpy determines a suitable datatype for this array.

Blindly attempting to change the datatype of an array is not wise:

>>> integer_array.dtype = np.float32
>>> integer_array
array([  2.80259693e-45,   0.00000000e+00,   2.80259693e-45,
         0.00000000e+00,   4.20389539e-45,   0.00000000e+00], dtype=float32)

Those numbers are gibberish you might say. That's because numpy tries to reinterpret the memory locations of that array as 4-byte floats (the skilled people will be able to convert the numbers to binary representation and from there reinterpret the original integer values).

If you want to cast, you'll have to do it explicitly and numpy will return a new array:

>>> integer_array.dtype = np.int64 # go back to the previous interpretation
>>> integer_array
array([2, 2, 3])
>>> integer_array.astype(np.float32)
array([ 2.,  2.,  3.], dtype=float32)

Now, to address your specific questions:

1a) If instantiate a with a = FourVector(ct=5,r=[55,2.,3]), then type(a._r[0]) returns numpy.float64 as opposed to numpy.int32. What is going on here? I expected just a._r[1] to be a float, and instead it changes the type of the whole list?

That's because numpy has to determine a datatype for the entire array (unless you use a structured array), ensuring all elements fit in that datatype. Only then can numpy iterate over the elements of that array efficiently.

1b) How do I get the above behaviour (The whole list being floats), without having to instantiate the variables as floats? I read up on the documentation and have tried various methods, like using astype(float), but everything I do seems to keep it as an int. Again, thinking this is the mutable/immutable problem I'm having.

Specify the dtype when you are creating the array. In your code, that would be:

self._r = np.array(r, dtype=np.float)

2) I had thought, in the tempx=... line, multiplying by 1.0 would convert it to a float, as it appears this is the reason ct converts to a float, but for some reason it doesn't. Perhaps the same reason as the others?

That is true. Try printing the datatype of tempx, it should be a float. However, later on, you are reinserting that value into the array self._r, which has the dtype of int. And as you saw previously, that will cast the float back to an integer type.

๐ŸŒ
NumPy
numpy.org โ€บ devdocs โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v2.5.dev0 Manual
A basic numerical type name combined with a numeric bitsize defines a concrete type. The bitsize is the number of bits that are needed to represent a single value in memory. For example, numpy.float64 is a 64 bit floating point data type. Some types, such as numpy.int_ and numpy.intp, have ...
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ 2.1 โ€บ reference โ€บ generated โ€บ numpy.ndarray.astype.html
numpy.ndarray.astype โ€” NumPy v2.1 Manual
Changed in version 1.9.0: Casting from numeric to string types in โ€˜safeโ€™ casting mode requires that the string dtype length is long enough to store the max integer/float value converted.
Top answer
1 of 2
2

Quantizing float32 to int8 loses a lot of information; if you do the obvious thing of scaling the floats to [-128,127] then you will lose far too much precision. You would also have to have some way of storing information about the reverse transformation to read it back correctly.

See https://huggingface.co/docs/optimum/en/concept_guides/quantization#quantization-to-int8 for a discussion of the issues.

If you're working in the context of an LLM or similar, then there is already going to be library support for quantizing the model properly to fp8.

Instead consider:

  • Just save as np.float16 to save some space and lose a little precision; very simple
  • Save with compression
  • Consider whether you can sparsify the tensor first. If you can sparsify a lot, then there are sparse representations that are more efficient. If not, then setting some near-0 values to 0 where it won't matter much can save storage when compressed.
2 of 2
2

It can be transformed into:

$x'=\lfloor x \frac{\lfloor \frac{2^b - 1}{2} \rfloor}{\max\lvert x \rvert} \rfloor$

Where $b$ is the number of bit, $x$ is the original float, and $x'$ is the integer representation.

Here is for the numpy where number of bit is 8:

def ieee754_to_signedint8(x, axis=-1):
  return ((x*127)/np.max(np.abs(x), axis=axis, keepdims=True)).astype(np.int8)

Tested:

But I still have unused information which is the value of -128, performing min-max of flattened vector will resulting, but not really, I can't guarantee whether there is existing -128 occured.

np.int8(-127), np.int8(127))
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ 1.22 โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v1.22 Manual
This should be taken into account when interfacing with low-level code (such as C or Fortran) where the raw memory is addressed. Data-types can be used as functions to convert python numbers to array scalars (see the array scalar section for an explanation), python sequences of numbers to arrays of that type, or as arguments to the dtype keyword that many numpy functions or methods accept. Some examples: >>> import numpy as np >>> x = np.float32(1.0) >>> x 1.0 >>> y = np.int_([1,2,4]) >>> y array([1, 2, 4]) >>> z = np.arange(3, dtype=np.uint8) >>> z array([0, 1, 2], dtype=uint8)
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ 2.1 โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v2.1 Manual
There are 5 basic numerical types representing booleans (bool), integers (int), unsigned integers (uint) floating point (float) and complex. A basic numerical type name combined with a numeric bitsize defines a concrete type. The bitsize is the number of bits that are needed to represent a ...
๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ 1.20 โ€บ user โ€บ basics.types.html
Data types โ€” NumPy v1.20 Manual
January 31, 2021 - This should be taken into account when interfacing with low-level code (such as C or Fortran) where the raw memory is addressed. Data-types can be used as functions to convert python numbers to array scalars (see the array scalar section for an explanation), python sequences of numbers to arrays of that type, or as arguments to the dtype keyword that many numpy functions or methods accept. Some examples: >>> import numpy as np >>> x = np.float32(1.0) >>> x 1.0 >>> y = np.int_([1,2,4]) >>> y array([1, 2, 4]) >>> z = np.arange(3, dtype=np.uint8) >>> z array([0, 1, 2], dtype=uint8)
๐ŸŒ
NumPy
numpy.org โ€บ devdocs โ€บ reference โ€บ generated โ€บ numpy.ndarray.astype.html
numpy.ndarray.astype โ€” NumPy v2.5.dev0 Manual
To avoid this, one should use a.real.astype(t). ... Try it in your browser! >>> import numpy as np >>> x = np.array([1, 2, 2.5]) >>> x array([1. , 2. , 2.5]) ... >>> x.astype(np.int_, casting="same_value") Traceback (most recent call last): ...
๐ŸŒ
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 ...