Converting floating-point arrays to integers is common in image processing, indexing operations, and data preparation. NumPy's astype() method handles this conversion, but understanding the different rounding behaviors is crucial for accurate results.
Fast Truncation with astype()
The simplest approach uses astype(int), which truncates toward zero (drops the decimal portion):
import numpy as np
arr = np.array([1.1, 2.9, 3.5, -1.7])
result = arr.astype(int)
print(result) # [ 1 2 3 -1]Rounding Before Conversion
For standard rounding (round half to nearest even), apply np.round() first:
import numpy as np
arr = np.array([1.1, 2.9, 3.5, 4.5])
rounded = np.round(arr).astype(int)
print(rounded) # [1 3 4 4]Understanding Banker's Rounding
NumPy uses "round half to even" (banker's rounding) by default:
import numpy as np
values = np.array([0.5, 1.5, 2.5, 3.5, 4.5])
print(np.round(values)) # [0. 2. 2. 4. 4.]
print(np.floor(values + 0.5).astype(int)) # [1 2 3 4 5]Floor, Ceil, and Trunc
Different rounding functions suit different use cases:
import numpy as np
arr = np.array([1.9, -1.9, 2.1, -2.1])
print(f"Original: {arr}") # Original: [ 1.9 -1.9 2.1 -2.1]
print(f"floor: {np.floor(arr).astype(int)}") # floor: [ 1 -2 2 -3]
print(f"ceil: {np.ceil(arr).astype(int)}") # ceil: [ 2 -1 3 -2]
print(f"trunc: {np.trunc(arr).astype(int)}") # trunc: [ 1 -1 2 -2]
print(f"round: {np.round(arr).astype(int)}") # round: [ 2 -2 2 -2]Behavior Comparison
| Function | Description | 1.9 | -1.9 | 1.1 | -1.1 |
|---|---|---|---|---|---|
np.floor() |
Round toward -∞ | 1 | -2 | 1 | -2 |
np.ceil() |
Round toward +∞ | 2 | -1 | 2 | -1 |
np.trunc() |
Round toward 0 | 1 | -1 | 1 | -1 |
np.round() |
Round to nearest | 2 | -2 | 1 | -1 |
astype(int) |
Same as trunc | 1 | -1 | 1 | -1 |
Practical Examples
Image Processing (0-255 Range)
import numpy as np
float_image = np.array([[0.0, 0.5, 1.0],
[0.25, 0.75, 0.9]])
int_image = np.round(float_image * 255).astype(np.uint8)
print(int_image)Output:
[[ 0 128 255]
[ 64 191 230]]Array Indexing
import numpy as np
indices = np.array([0.7, 1.2, 2.9, 3.1])
data = np.array([10, 20, 30, 40, 50])
int_indices = indices.astype(int)
print(data[int_indices]) # [10 20 30 40]
int_indices = np.round(indices).astype(int)
print(data[int_indices]) # [20 20 30 40]Output:
[10 20 30 40]
[20 20 40 40]Binning Data
import numpy as np
values = np.array([0.0, 0.3, 0.7, 1.2, 1.8, 2.5])
bins = np.floor(values).astype(int)
print(bins) # [0 0 0 1 1 2]Handling Overflow
Large floats may overflow when converted to smaller integer types:
import numpy as np
large_values = np.array([1e10, 1e15, 1e18])
safe = large_values.astype(np.int64)
print(safe) # [10000000000 1000000000000000 1000000000000000000]
overflow = large_values.astype(np.int32)
print(overflow) # [-2147483648 -2147483648 -2147483648] ← Wrong!Output:
[ 10000000000 1000000000000000 1000000000000000000]
RuntimeWarning: invalid value encountered in cast
[-2147483648 -2147483648 -2147483648]Checking Before Conversion
import numpy as np
def safe_float_to_int(arr, dtype=np.int64):
"""Convert float array to int with overflow checking."""
arr = np.asarray(arr)
info = np.iinfo(dtype)
if arr.min() < info.min or arr.max() > info.max:
raise OverflowError(
f"Values {arr.min():.2e} to {arr.max():.2e} "
f"exceed {dtype} range [{info.min}, {info.max}]"
)
return arr.astype(dtype)
arr = np.array([1e5, 1e10, 1e15])
try:
result = safe_float_to_int(arr, np.int32)
except OverflowError as e:
print(f"Error: {e}")
result = safe_float_to_int(arr, np.int64) # Use larger typeOutput:
Error: Values 1.00e+05 to 1.00e+15 exceed <class 'numpy.int32'> range [-2147483648, 2147483647]Special Values: NaN and Inf
Handle special floating-point values before conversion:
import numpy as np
arr = np.array([1.5, np.nan, np.inf, -np.inf, 2.5])
print(arr.astype(int)) # Platform-dependent results!
clean = np.nan_to_num(arr, nan=0, posinf=0, neginf=0)
print(clean.astype(int)) # [1 0 0 0 2]
mask = np.isfinite(arr)
result = np.zeros_like(arr, dtype=int)
result[mask] = arr[mask].astype(int)
print(result) # [1 0 0 0 2]Output:
RuntimeWarning: invalid value encountered in cast
[ 1 -9223372036854775808 -9223372036854775808
-9223372036854775808 2]
[1 0 0 0 2]
[1 0 0 0 2]Choosing Integer Types
Select the appropriate integer type based on your data:
import numpy as np
arr = np.array([1.5, 2.5, 3.5])
arr.astype(int)
arr.astype(np.int8) # -128 to 127
arr.astype(np.int16) # -32,768 to 32,767
arr.astype(np.int32) # ±2.1 billion
arr.astype(np.int64) # ±9.2 quintillion
arr.astype(np.uint8) # 0 to 255 (common for images)
arr.astype(np.uint16) # 0 to 65,535Quick Reference
| Goal | Method | 2.9 → | -2.9 → |
|---|---|---|---|
| Fast truncation | astype(int) |
2 | -2 |
| Round to nearest | round().astype(int) |
3 | -3 |
| Always round down | floor().astype(int) |
2 | -3 |
| Always round up | ceil().astype(int) |
3 | -2 |
| Truncate toward zero | trunc().astype(int) |
2 | -2 |
Summary
- Use
astype(int)for quick truncation when speed matters and decimal loss is acceptable. - Use
np.round().astype(int)when you need mathematically correct rounding. - Choose
floor()for binning operations - Use
ceil()when you need to round up. - Always verify your values fit within the target integer type's range to avoid silent overflow errors.