Python NumPy: How to Convert a NumPy Float Array to Integer in Python
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]
astype(int) truncates rather than rounds. The value 2.9 becomes 2, not 3. This behavior surprises many users expecting mathematical rounding.
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])
# Round then convert
rounded = np.round(arr).astype(int)
print(rounded) # [1 3 4 4]
# Note: 3.5 → 4 and 4.5 → 4 (banker's rounding)
Understanding Banker's Rounding
NumPy uses "round half to even" (banker's rounding) by default:
import numpy as np
# Values ending in .5 round to nearest even number
values = np.array([0.5, 1.5, 2.5, 3.5, 4.5])
print(np.round(values)) # [0. 2. 2. 4. 4.]
# To always round .5 up, add a tiny epsilon
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 |
Use floor() for binning and histogram calculations. Use round() when you need the mathematically closest integer. Use ceil() when you need to round up (e.g., calculating required array sizes).
Practical Examples
Image Processing (0-255 Range)
import numpy as np
# Normalized float image (0.0 to 1.0)
float_image = np.array([[0.0, 0.5, 1.0],
[0.25, 0.75, 0.9]])
# Convert to 8-bit integers (0-255)
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
# Calculated indices (floats)
indices = np.array([0.7, 1.2, 2.9, 3.1])
# Must convert to int for indexing
data = np.array([10, 20, 30, 40, 50])
# Using truncation (rounds down for positive)
int_indices = indices.astype(int)
print(data[int_indices]) # [10 20 30 40]
# Using round for nearest index
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
# Continuous values to bin into integer categories
values = np.array([0.0, 0.3, 0.7, 1.2, 1.8, 2.5])
# Floor gives the bin number (0, 1, 2...)
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])
# int64 handles large values safely
safe = large_values.astype(np.int64)
print(safe) # [10000000000 1000000000000000 1000000000000000000]
# int32 overflows!
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)
# Get type limits
info = np.iinfo(dtype)
# Check for values outside range
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)
# Usage
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 type
Output:
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])
# Direct conversion gives undefined behavior
print(arr.astype(int)) # Platform-dependent results!
# Clean approach: replace special values first
clean = np.nan_to_num(arr, nan=0, posinf=0, neginf=0)
print(clean.astype(int)) # [1 0 0 0 2]
# Or mask and handle separately
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])
# Standard integer (platform-dependent size)
arr.astype(int)
# Explicit sizes
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
# Unsigned (non-negative only)
arr.astype(np.uint8) # 0 to 255 (common for images)
arr.astype(np.uint16) # 0 to 65,535
Quick 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.