Skip to content

Python NumPy: How to Change NumPy Array Data Type in Python

Learn how to convert NumPy array data types using astype() for memory optimization, precision control, and compatibility with operations like machine learning and image processing.

Converting between data types is essential for memory optimization, mathematical operations, and compatibility with different libraries. NumPy's astype() method provides flexible type conversion while preserving array structure.

Using astype()

The astype() method creates a new array with the specified data type:

import numpy as np

arr = np.array([1, 2, 3])
print(f"Original type: {arr.dtype}")    # int64 (or int32 on Windows)

float_arr = arr.astype('float64')
print(f"New type: {float_arr.dtype}")   # float64
print(float_arr)                        # [1. 2. 3.]

Output:

Original type: int64
New type: float64
[1. 2. 3.]

Multiple Ways to Specify Types

import numpy as np

arr = np.array([1, 2, 3])

arr.astype('float64')

arr.astype(np.float64)

arr.astype(float)

arr.astype('f8')  # 'f8' = float64 (8 bytes)

Common Data Types

Type String Shorthand Bytes Range/Precision
Integer 8-bit 'int8' 'i1' 1 -128 to 127
Integer 16-bit 'int16' 'i2' 2 -32,768 to 32,767
Integer 32-bit 'int32' 'i4' 4 ±2.1 billion
Integer 64-bit 'int64' 'i8' 8 ±9.2 quintillion
Unsigned 8-bit 'uint8' 'u1' 1 0 to 255
Float 16-bit 'float16' 'f2' 2 ~3 decimal digits
Float 32-bit 'float32' 'f4' 4 ~7 decimal digits
Float 64-bit 'float64' 'f8' 8 ~15 decimal digits
Boolean 'bool' '?' 1 True/False
Complex 'complex128' 'c16' 16 Complex numbers

Type Conversion Examples

Integer to Float

import numpy as np

int_arr = np.array([1, 2, 3, 4, 5])
float_arr = int_arr.astype(float)

print(float_arr)        # [1. 2. 3. 4. 5.]
print(float_arr.dtype)  # float64

Output:

[1. 2. 3. 4. 5.]
float64

Float to Integer (Truncation Warning)

import numpy as np

float_arr = np.array([1.9, 2.1, 3.5, -1.7])

int_arr = float_arr.astype(int)
print(int_arr)  # [1 2 3 -1]

rounded = np.round(float_arr).astype(int)
print(rounded)  # [2 2 4 -2]

Output:

[ 1  2  3 -1]
[ 2  2  4 -2]

Numeric to Boolean

import numpy as np

arr = np.array([0, 1, 2, -1, 0, 5])
bool_arr = arr.astype(bool)

print(bool_arr)  # [False  True  True  True False  True]

Output:

[False  True  True  True False  True]

Boolean to Numeric

import numpy as np

bool_arr = np.array([True, False, True, True])

int_arr = bool_arr.astype(int)
print(int_arr)      # [1 0 1 1]

float_arr = bool_arr.astype(float)
print(float_arr)    # [1. 0. 1. 1.]

Output:

[1 0 1 1]
[1. 0. 1. 1.]

String Conversions

import numpy as np

num_arr = np.array([1, 2, 3])
str_arr = num_arr.astype(str)
print(str_arr)          # ['1' '2' '3']
print(str_arr.dtype)    # <U21 (Unicode string)

str_arr = np.array(['1.5', '2.7', '3.9'])
float_arr = str_arr.astype(float)
print(float_arr)        # [1.5 2.7 3.9]

Output:

['1' '2' '3']
<U21
[1.5 2.7 3.9]

Memory Optimization

Smaller data types reduce memory usage for large arrays:

import numpy as np

large_arr = np.arange(1_000_000)
print(f"int64 size: {large_arr.nbytes / 1e6:.1f} MB")  # 8.0 MB

small_arr = large_arr.astype(np.int8)
print(f"int8 size: {small_arr.nbytes / 1e6:.1f} MB")   # 1.0 MB

float64_arr = np.random.rand(1_000_000)
print(f"float64: {float64_arr.nbytes / 1e6:.1f} MB")   # 8.0 MB

float32_arr = float64_arr.astype(np.float32)
print(f"float32: {float32_arr.nbytes / 1e6:.1f} MB")   # 4.0 MB

Output:

int64 size: 8.0 MB
int8 size: 1.0 MB
float64: 8.0 MB
float32: 4.0 MB

Overflow Warning

Smaller types have limited ranges-exceeding them causes overflow:

import numpy as np

arr = np.array([100, 200, 300])

int8_arr = arr.astype(np.int8)
print(int8_arr)  # [100  -56   44]  ← Overflow!

uint8_arr = arr.astype(np.uint8)
print(uint8_arr)  # [100 200  44]  ← 300 overflows

if arr.max() <= 127 and arr.min() >= -128:
    safe_arr = arr.astype(np.int8)
else:
    print("Values out of int8 range!")

Output:

[100 -56  44]
[100 200  44]
Values out of int8 range!

Checking and Comparing Types

import numpy as np

arr = np.array([1.5, 2.5, 3.5])

print(arr.dtype)                                # float64
print(arr.dtype.name)                           # 'float64'
print(arr.dtype.itemsize)                       # 8 (bytes per element)

print(arr.dtype == np.float64)                  # True
print(np.issubdtype(arr.dtype, np.floating))    # True
print(np.issubdtype(arr.dtype, np.integer))     # False

Output:

float64
float64
8
True
True
False

Setting Type at Creation

Specify dtype when creating arrays to avoid conversion overhead:

import numpy as np

arr = np.array([1, 2, 3], dtype=np.float32)
print(arr.dtype)  # float32

zeros = np.zeros((3, 3), dtype=np.int8)
ones = np.ones((2, 2), dtype=np.float32)

integers = np.arange(10, dtype=np.int16)

Output:

float32

Copy vs View Behavior

astype() always creates a copy, even when the type doesn't change:

import numpy as np

arr = np.array([1, 2, 3], dtype=np.int32)

same_type = arr.astype(np.int32)
same_type[0] = 99

print(arr)        # [1 2 3] (unchanged)
print(same_type)  # [99 2 3]

no_copy = arr.astype(np.int32, copy=False)

Output:

[1 2 3]
[99  2  3]

Practical Examples

Preparing Data for Image Processing

import numpy as np

image_float = np.random.rand(100, 100) * 255

image_uint8 = image_float.astype(np.uint8)
print(f"Type: {image_uint8.dtype}, Range: {image_uint8.min()}-{image_uint8.max()}")

Output:

Type: uint8, Range: 0-254

Optimizing ML Features

import numpy as np

features = np.random.randn(10000, 100)  # float64 default
print(f"Original: {features.nbytes / 1e6:.1f} MB")

features_32 = features.astype(np.float32)
print(f"Optimized: {features_32.nbytes / 1e6:.1f} MB")

Output:

Original: 8.0 MB
Optimized: 4.0 MB

Converting Categorical Labels

import numpy as np

labels = np.array(['cat', 'dog', 'cat', 'bird', 'dog'])

unique_labels = np.unique(labels)
label_to_int = {label: i for i, label in enumerate(unique_labels)}

numeric_labels = np.array([label_to_int[l] for l in labels])
print(numeric_labels)  # [1 2 1 0 2] (bird=0, cat=1, dog=2)

Output:

[1 2 1 0 2]

Quick Reference

Goal Command
To float64 arr.astype(float) or arr.astype(np.float64)
To int64 arr.astype(int) or arr.astype(np.int64)
To float32 (GPU) arr.astype(np.float32)
To uint8 (images) arr.astype(np.uint8)
To boolean arr.astype(bool)
To string arr.astype(str)
Check type arr.dtype
Memory size arr.nbytes

Summary

Use astype() to convert NumPy array data types.

Remember that float-to-integer conversion truncates rather than rounds. Choose smaller types like float32 or int16 to reduce memory usage for large arrays, but verify your data fits within the type's range to avoid overflow. Specify dtype at array creation when possible to avoid unnecessary conversion steps.

Navigation