Data Types (dtype)
Understand NumPy dtypes (int32, int64, float64, bool, str …), set them with dtype=, convert with astype, and avoid overflow and precision traps.
Every NumPy array has exactly one data type for all its elements. Runs are whole numbers (int), strike rates have decimals (float), "did he score a fifty?" is True/False (bool), names are text (str). Choosing the right dtype affects memory, speed and correctness.
Definition
A dtype (data type) is an object that describes how each element of an array is stored in memory: its kind (integer, float, boolean, string …) and its size in bytes. Every element of an ndarray has the same dtype, available as
arr.dtype.
- Kind — what sort of value: signed int, unsigned int, float, complex, bool, string.
- Size (bits/bytes) — the number in names like
int32orfloat64is the number of bits. 8 bits = 1 byte, soint64uses 8 bytes per element. - Fixed size — this is what lets NumPy store elements back-to-back and compute on them in C.
Common dtypes
| dtype | Kind | Bytes | Range / precision | Cricket use |
|---|---|---|---|---|
int8 | signed integer | 1 | −128 to 127 | wickets in a match |
int32 | signed integer | 4 | about ±2.1 billion | runs |
int64 | signed integer | 8 | about ±9.2 × 10¹⁸ | default int |
uint8 | unsigned integer | 1 | 0 to 255 | image pixel values |
float32 | floating point | 4 | ~6–7 significant digits | ML model weights |
float64 | floating point | 8 | ~15–16 significant digits | default float: averages, strike rates |
complex128 | complex | 16 | two float64s | signal processing |
bool | boolean | 1 | True / False | "scored a fifty?" |
<U5 | Unicode string | 4 per character | max 5 characters | player names |
Example — what dtype does NumPy infer?
python
import numpy as np
for name, arr in [
("int", np.array([72, 45, 88])),
("float", np.array([72.0, 45.5])),
("bool", np.array([True, False])),
("str", np.array(["Virat", "Rohit"])),
("complex", np.array([1 + 2j])),
]:
print(f"{name:<8} dtype={str(arr.dtype):<8} itemsize={arr.itemsize}")text
int dtype=int64 itemsize=8
float dtype=float64 itemsize=8
bool dtype=bool itemsize=1
str dtype=<U5 itemsize=20
complex dtype=complex128 itemsize=16How it works: itemsize is bytes per element. <U5 means "little-endian Unicode string, max 5 characters"; each character takes 4 bytes, so 5 × 4 = 20.
Syntax — setting and converting dtypes
python
np.array(data, dtype=...) # choose the dtype at creation
arr.astype(dtype, copy=True) # convert to a new dtype (returns a new array)| Parameter | Meaning | Default |
|---|---|---|
dtype | Python type (int, float, bool, str), NumPy type (np.int32) or string ("float32") | inferred |
copy (astype) | False returns the same array if no conversion is needed | True |
python
import numpy as np
a = np.array([72, 45, 88], dtype=np.int32)
print(a, a.dtype, a.itemsize)
b = np.array([72, 45, 88], dtype="float32")
print(b, b.dtype, b.itemsize)
c = np.array([1, 0, 2], dtype=bool)
print(c)
d = np.array([72, 45, 88], dtype="int8")
print(d.dtype, d.nbytes)
print(np.dtype("int64") == np.int64, np.dtype(float), np.dtype(int))text
[72 45 88] int32 4
[72. 45. 88.] float32 4
[ True False True]
int8 3
True float64 int64How it works: dtype accepts many spellings. Python's float maps to float64 and int to int64 (on NumPy 2). Converting to bool: 0 → False, anything else → True. An int8 array of 3 values takes only 3 bytes.
Example — astype conversions
python
import numpy as np
strike_rates = np.array([145.7, 132.2, 98.9])
as_int = strike_rates.astype(int)
print(as_int, as_int.dtype)
print(strike_rates)
print(np.round(strike_rates).astype(int))
text = np.array(["72", "45", "88"])
nums = text.astype(int)
print(nums, nums.sum())
print(np.array([0, 3, 0, 7]).astype(bool))
print(np.array([72, 45]).astype(str))
print(np.array([-2.7, 2.7]).astype(int))text
[145 132 98] int64
[145.7 132.2 98.9]
[146 132 99]
[72 45 88] 205
[False True False True]
['72' '45']
[-2 2]How it works:
astypereturns a new array; the originalstrike_ratesis unchanged.- Float → int truncates toward zero (98.9 → 98, −2.7 → −2). Round first if you want 99.
- String → int works when the text contains valid numbers — very handy for cleaning data read from files.
- Numbers → bool marks non-zero values as True.
Overflow — integers have limits
python
import numpy as np
a = np.array([100, 120, 127], dtype=np.int8)
print(a + 1)
print(np.iinfo(np.int32).max, np.iinfo(np.int64).max)
try:
np.array([300], dtype=np.int8)
except OverflowError as e:
print("OverflowError:", e)
print(np.array([300]).astype(np.int8))text
[ 101 121 -128]
2147483647 9223372036854775807
OverflowError: Python integer 300 out of bounds for int8
[44]How it works: int8 can hold at most 127. 127 + 1 wraps around to −128 — silently, with no error! Creating an array directly from an out-of-range Python int raises OverflowError, but astype wraps silently (300 → 44). np.iinfo(dtype) tells you the min/max of any integer type.
Precision — floats are approximate
python
import numpy as np
print(0.1 + 0.2)
print(np.float64(0.1) + np.float64(0.2) == 0.3)
print(np.isclose(0.1 + 0.2, 0.3))
print(np.float32(1/3), np.float64(1/3))
print(np.array([16777217], dtype=np.float32))text
0.30000000000000004
False
True
0.33333334 0.3333333333333333
[1.6777216e+07]How it works: floats are stored in binary, so 0.1 and 0.2 are each a tiny bit off. Never compare floats with ==; use np.isclose (or np.allclose for arrays). float32 keeps only ~7 digits — it cannot even store 16,777,217 exactly (it becomes 16,777,216).
Assignment never changes the dtype
python
import numpy as np
x = np.array([1, 2, 3])
x[0] = 9.99
print(x)
names = np.array(["Virat", "Rohit"])
names[1] = "Suryakumar"
print(names, names.dtype)text
[9 2 3]
['Virat' 'Surya'] <U5The int array truncates 9.99 to 9, and the <U5 string array cuts "Suryakumar" to "Surya" — 5 characters max. Convert with astype (e.g. names.astype("<U20")) before assigning longer values.
Common mistakes
- ❌ Expecting
astype(int)to round. ✅np.round(x).astype(int). - ❌ Using
int8/int16to "save memory" on values that can grow (totals, sums). ✅ Stick toint64unless you know the range. - ❌
if a == 0.3with floats. ✅np.isclose(a, 0.3). - ❌ Forgetting that
astypereturns a new array. ✅arr = arr.astype(float). - ❌ Silent string truncation in
<Uarrays. ✅ Create with enough length or useastype.
Interview tip
Q: What happens when an int8 array value exceeds 127?
A: Arithmetic on the array wraps around (127 + 1 → −128) silently, because the value no longer fits in 8 bits. Choose a wider dtype (int32/int64) when values can grow, and check limits with np.iinfo.
Key points to remember
- A dtype describes the kind (int, float, bool, str …) and size in bytes of every element; one dtype per array.
- Defaults on NumPy 2: whole numbers → int64, decimals → float64, True/False → bool, text → <U(n).
- Set the type with dtype= at creation, or convert later with arr.astype(new_type), which returns a new array.
- Float → int conversion truncates toward zero; round first if needed.
- Integer dtypes have fixed ranges: int8 holds −128..127 and array arithmetic wraps around silently on overflow.
- Floats are approximate (0.1 + 0.2 != 0.3); compare them with np.isclose.
- Assigning into an array never changes its dtype — values are cast (9.99 → 9, long strings truncated).
Try it yourself
Inspect dtypes and memory
astype: cleaning text scores
Overflow and precision traps
Practice: pick the right dtypes
Revision Flashcards
Tap a card to flip it and see the answer.
