NumPy: dtype Data Types

Last updated: 2026-08-26

dtype Data Types

1. What You'll Learn



2. Story

Alice's model accuracy dropped from 95% to 12% overnight. The culprit: converting float64 to int8 overflowed all values above 127 into negatives. "dtype isn't a minor detail — pick the wrong type and your data is ruined."



3. Key Concepts

(1) The dtype System

NumPy's dtype (data type) describes the type of every element in an array. Every ndarray has a .dtype attribute.

TEXT 📖 Display only
np.int32    # 32-bit signed integer
np.float64  # 64-bit floating point
np.bool_    # boolean
np.str_     # unicode string
np.object_  # Python object

dtype has two fields:

Field Meaning Example
kind Type category 'i'=int, 'f'=float, 'u'=uint, 'b'=bool
itemsize Bytes per element 4 for int32
PYTHON
import numpy as np

a = np.array([1, 2, 3])
print(a.dtype)       # int64 (on 64-bit platforms)
print(a.dtype.kind)  # 'i'
print(a.dtype.itemsize)  # 8
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.


(2) Integer Type Comparison

Type Range Bytes Alias
int8 -128 ~ 127 1
int16 -32768 ~ 32767 2
int32 -2147483648 ~ 2147483647 4 intp (32-bit)
int64 -9223372036854775808 ~ 9223372036854775807 8 intp (64-bit)
uint8 0 ~ 255 1
uint16 0 ~ 65535 2
uint32 0 ~ 4294967295 4
uint64 0 ~ 18446744073709551615 8

(3) Float Type Comparison

Type Bytes Precision Max Min Positive
float16 2 ~3 digits 65504 5.96e-8
float32 4 ~7 digits 3.4e38 1.18e-38
float64 8 ~15 digits 1.8e308 2.23e-308
float128 16 ~33 digits 1.19e4932 3.36e-4932
⚠️ Note: float128 on many platforms is actually 80-bit extended precision padded to 128 bits, not true 128-bit.


(4) Specifying dtype

PYTHON
import numpy as np

# By NumPy type object
a = np.array([1, 2, 3], dtype=np.float32)

# By string
b = np.array([1, 2, 3], dtype='float32')

# By single-character code
c = np.array([1, 2, 3], dtype='f4')  # float32: 'f' + 4 bytes
Character Type Example
b boolean np.dtype('b')
i signed int np.dtype('i4') = int32
u unsigned int np.dtype('u1') = uint8
f float np.dtype('f8') = float64
c complex np.dtype('c16') = complex128
S byte string np.dtype('S10') = 10-char string
U unicode string np.dtype('U5') = 5-char unicode

(5) Type Conversion and Overflow

PYTHON
import numpy as np

# astype returns a new array with the target dtype
a = np.array([1, 2, 3], dtype=np.int32)
b = a.astype(np.float64)  # [1. 2. 3.]

# Overflow: values beyond the target range wrap around
c = np.array([100, 200, 300], dtype=np.uint8)
# [100, 200, 44]  — 300 - 256 = 44

# Float to int truncates
d = np.array([1.9, 2.5, 3.1])
print(d.astype(np.int32))  # [1 2 3]

Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (pip install numpy) and compare. Actual values may vary by NumPy version and random seed.

(6) Structured dtypes

For tabular data with mixed types, use structured dtypes:

PYTHON
import numpy as np

# Define a structured dtype
dt = np.dtype([('name', 'U10'), ('age', 'i4'), ('salary', 'f8')])

# Create array with structured dtype
employees = np.array([
    ('Alice', 30, 75000.0),
    ('Bob', 25, 62000.0),
    ('Charlie', 35, 85000.0)
], dtype=dt)

print(employees['name'])   # ['Alice' 'Bob' 'Charlie']
print(employees['salary'].mean())  # 74000.0

Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (pip install numpy) and compare. Actual values may vary by NumPy version and random seed.


▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: Overflow demonstration (Difficulty ⭐⭐)

PYTHON
import numpy as np

# int8 range: -128 to 127
vals = np.array([100, 120, 127, 128, 130, 200], dtype=np.int8)
print("int8 values:", vals)
# [100  120  127 -128 -126  -56]

# uint8 range: 0 to 255
vals_u = np.array([200, 255, 256, 300], dtype=np.uint8)
print("uint8 values:", vals_u)
# [200 255   0  44]
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: Structured dtype — employee records (Difficulty ⭐⭐)

PYTHON
import numpy as np

dt = np.dtype([('name', 'U10'), ('dept', 'U15'), ('salary', 'f8'), ('years', 'i2')])

data = np.array([
    ('Alice', 'Engineering', 95000, 5),
    ('Bob', 'Marketing', 72000, 3),
    ('Charlie', 'Engineering', 110000, 8),
    ('Diana', 'Sales', 68000, 2),
], dtype=dt)

# Query by department
eng = data[data['dept'] == 'Engineering']
print("Engineering avg salary:", eng['salary'].mean())

# Sort by salary
sorted_data = np.sort(data, order='salary')
print("Top earner:", sorted_data[-1]['name'], sorted_data[-1]['salary'])
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.


4. Comparison Tables

(1) Type Casting Rules

Source ↓ / Target → int float complex string
int ✅ (safe) ✅ (safe) ✅ (decimal)
float ⚠️ truncates ✅ (safe) ✅ (decimal)
complex ⚠️ loses imag ⚠️ loses imag ✅ (string)
bool ✅ (0/1) ✅ (0.0/1.0)

(2) Memory vs Precision Matrix

dtype 1M elements Relative to float64 Use case
float16 2 MB 25% GPU training, storage
float32 4 MB 50% Deep learning, most ML
float64 8 MB 100% Scientific computing
int8 1 MB 12.5% Image bytes, flags
int32 4 MB 50% General integer
int64 8 MB 100% Large indices, timestamps

(3) Overflow Behavior

Operation int8 uint8 float32
Max + 1 -128 (wrap) 0 (wrap) inf
Min - 1 127 (wrap) 255 (wrap) -inf
0 / 0 error error nan


5. Principle Diagram

100%
graph TB
    A[Python object] --> B{dtype inference}
    B -->|int| C[int64]
    B -->|float| D[float64]
    B -->|mixed| E[upcast to common type]
    B -->|explicit| F[user-specified dtype]
    C --> G[ndarray with fixed dtype]
    D --> G
    E --> G
    F --> G
    G --> H[vectorized operations]
    G --> I[memory-efficient storage]
    
    style A fill:#e1f5fe
    style G fill:#c8e6c9
    style H fill:#fff9c4
    style I fill:#fff9c4

▶ Example: dtype conversion and memory usage (Difficulty ⭐⭐)

PYTHON
import numpy as np

# Compare memory usage of different dtypes
arr_int64 = np.ones(1000000, dtype=np.int64)
arr_float32 = np.ones(1000000, dtype=np.float32)
arr_int8 = np.ones(1000000, dtype=np.int8)

print(f"int64:  {arr_int64.nbytes / 1e6:.1f} MB")
print(f"float32: {arr_float32.nbytes / 1e6:.1f} MB")
print(f"int8:   {arr_int8.nbytes / 1e6:.1f} MB")

# Convert between types
converted = arr_float32.astype(np.int32)
print(f"Converted dtype: {converted.dtype}")

Output:

TEXT 📖 Display only
int64:  8.0 MB
float32: 4.0 MB
int8:   1.0 MB
Converted dtype: int32


❓ FAQ

Q What's the default integer dtype?
A int64 on 64-bit platforms, int32 on 32-bit. NumPy chooses based on your system architecture. You can always specify explicitly with dtype=np.int32.
Q What happens when I overflow an integer?
A It wraps around silently — no error, no warning. int8(127) + 1 = -128. This is a common source of bugs. Use np.seterr(over='warn') to catch it.
Q When should I use float32 vs float64?
A Use float64 for scientific computing where precision matters. Use float32 for deep learning (GPUs are faster with float32) or when memory is tight. float32 has ~7 digits of precision — enough for most ML tasks.
Q What's the difference between 'f' and 'd'?
A 'f' = float32 (4 bytes), 'd' = float64 (8 bytes). These are single-character codes from C's float and double.
Q Can I have mixed types in one array?
A Not in a regular ndarray. But you can use structured dtypes (like a database table with named columns) or object dtype (which stores Python object references, losing performance).

📖 Summary



📝 Exercises

  1. Beginner (Difficulty ⭐): Create arrays of int8, int16, int32, int64, float32, float64 — each with 1000 elements of value 1. Print their nbytes and explain the memory differences.

  2. Intermediate (Difficulty ⭐⭐): Create a uint8 array with values [0, 127, 128, 255, 256, -1]. Observe which values overflow and explain the results. Then create a structured dtype for a book catalog with fields: title (string), author (string), year (int16), price (float32).

  3. Advanced (Difficulty ⭐⭐⭐): Convert a float64 array of 1 million random numbers to float32, then back to float64. Compute the mean absolute error between the original and the round-tripped array. Repeat with float16. Record the precision loss for each type.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏