Skip to content

NumPy Data Types (dtypes)

What is a dtype?

A dtype (data type) tells NumPy what kind of values an array contains, such as:

  • integers (int32int32, int64int64)
  • floats (float32float32, float64float64)
  • booleans (boolbool)
  • strings (<U...<U...) and bytes (|S...|S...)

Because NumPy uses a single dtype for the entire array, it can store values efficiently and run fast computations. A dtype name is really just a hint about memory layout: a type name (intint, floatfloat) followed by the number of bits per element. A standard double-precision float takes 8 bytes (64 bits) — hence float64float64.

diagram How NumPy infers a dtype mermaid
numpy.array walks the input data once and picks the narrowest common dtype that can hold every value.

Checking dtype

check
import numpy as np
 
arr = np.array([1, 2, 3])
print(arr.dtype)
check
import numpy as np
 
arr = np.array([1, 2, 3])
print(arr.dtype)

Common numeric dtypes

Integers

ints
a = np.array([1, 2, 3], dtype=np.int32)
b = np.array([1, 2, 3], dtype=np.int64)
print(a.dtype, b.dtype)
ints
a = np.array([1, 2, 3], dtype=np.int32)
b = np.array([1, 2, 3], dtype=np.int64)
print(a.dtype, b.dtype)

Floats

floats
a = np.array([1.5, 2.0, 3.25], dtype=np.float32)
b = np.array([1.5, 2.0, 3.25], dtype=np.float64)
print(a.dtype, b.dtype)
floats
a = np.array([1.5, 2.0, 3.25], dtype=np.float32)
b = np.array([1.5, 2.0, 3.25], dtype=np.float64)
print(a.dtype, b.dtype)

Memory usage and dtype

Smaller dtypes use less memory. Every element in a float32float32 array takes 4 bytes; every element in a float64float64 array takes 8 bytes — double the space for the same number of values.

memory
import numpy as np
 
arr32 = np.ones(1_000_000, dtype=np.float32)
arr64 = np.ones(1_000_000, dtype=np.float64)
 
print("float32 bytes:", arr32.nbytes)
print("float64 bytes:", arr64.nbytes)
memory
import numpy as np
 
arr32 = np.ones(1_000_000, dtype=np.float32)
arr64 = np.ones(1_000_000, dtype=np.float64)
 
print("float32 bytes:", arr32.nbytes)
print("float64 bytes:", arr64.nbytes)
sketch Memory layout: int8 vs int64 p5.js
Each block is one byte. A single int64 element takes as much memory as eight int8 elements.

Type conversion

Using .astype().astype()

astype
import numpy as np
 
arr = np.array([1, 2, 3])
arr_f = arr.astype(np.float64)
print(arr_f, arr_f.dtype)
astype
import numpy as np
 
arr = np.array([1, 2, 3])
arr_f = arr.astype(np.float64)
print(arr_f, arr_f.dtype)

Safe conversion (avoid overflow)

Converting large values into a smaller dtype can overflow.

overflow
import numpy as np
 
arr = np.array([300], dtype=np.int16)
print(arr.astype(np.uint8))  # wraps around in many cases
overflow
import numpy as np
 
arr = np.array([300], dtype=np.int16)
print(arr.astype(np.uint8))  # wraps around in many cases

Dtype pitfalls in data analytics

1) Missing values

NumPy numeric arrays can’t store NaNNaN in integer dtype.

nan-int
import numpy as np
 
# This will upcast to float automatically because of np.nan
arr = np.array([1, 2, np.nan])
print(arr)
print(arr.dtype)
nan-int
import numpy as np
 
# This will upcast to float automatically because of np.nan
arr = np.array([1, 2, np.nan])
print(arr)
print(arr.dtype)

2) Mixed types

If you mix strings and numbers, dtype may become objectobject or strings.

mixed
import numpy as np
 
arr = np.array([1, "two", 3])
print(arr)
print(arr.dtype)
mixed
import numpy as np
 
arr = np.array([1, "two", 3])
print(arr)
print(arr.dtype)

Arrays with dtype=objectdtype=object are slower for numerical operations.

Next

Continue to: Indexing and Slicing Arrays to learn how to select, filter, and extract parts of arrays.

🧪 Try It Yourself

Exercise 1 – Check and Set dtype

Exercise 2 – Convert with astype()

Exercise 3 – Memory Cost of a dtype

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did