Skip to content

NumPy - Data Types

Every NumPy array (ndarray) is a collection of elements of the same data type. NumPy offers a much wider variety of numerical data types compared to standard Python, allowing for fine-grained control over memory usage and precision. This data type information is encapsulated in a data type object (dtype) associated with each array.

A dtype object provides metadata about how the bytes in the array’s memory block should be interpreted. This includes:

  • Type: The kind of data (e.g., integer, float, boolean, complex, string).
  • Size: The number of bytes per element (e.g., int64 uses 8 bytes).
  • Byte Order: The endianness (byte order: little-endian or big-endian) of the data.
  • Structure (for Structured Arrays): Field names, the data type of each field, and the memory layout.
  • Sub-array Shape (if applicable): For data types representing arrays within arrays.

Here’s a table listing some of the most commonly used built-in scalar data types in NumPy. You can typically access them via np.<type_name> (e.g., np.int64, np.float32).

TypeDescription
np.bool_Boolean (True or False), stored as a single byte.
np.int8, np.int16, np.int32, np.int64Signed integers of varying sizes (8, 16, 32, 64 bits). np.int_ is the default integer type (usually np.int64).
np.uint8, np.uint16, np.uint32, np.uint64Unsigned integers of varying sizes.
np.float16, np.float32, np.float64Floating-point numbers with different precision (half, single, double). np.float_ is the default float type (usually np.float64).
np.complex64, np.complex128Complex numbers represented by pairs of floats (two 32-bit or two 64-bit floats). np.complex_ defaults to np.complex128.
np.str_Unicode string type. Compatible with Python str. Uses variable-length strings.
np.bytes_Byte string type. Compatible with Python bytes. Uses variable-length strings.
np.datetime64Date and time values, with various units (e.g., [Y], [M], [D], [h], [m], [s], [ms], [us], [ns]).
np.timedelta64Represents differences between two datetime64 values.
np.object_Represents Python objects. Allows arrays to hold elements of different types (discouraged if performance is critical).
np.voidRepresents raw, unstructured data blocks. Often used as the container for structured arrays.

You can explicitly create dtype objects using numpy.dtype(). This is often needed for defining structured arrays or specifying precise type details like endianness.

numpy.dtype(object, align=False, copy=False)

The object parameter can be:

  • A NumPy type object (e.g., np.int32).
  • A type character code string (e.g., 'i4' for 4-byte integer, 'f8' for 8-byte float, 'U' for Unicode string).
  • A string specifying type with endianness (e.g., '>i4' for big-endian 4-byte integer, '<f8' for little-endian 8-byte float). = means native endianness.
  • A list of tuples for structured arrays (see below).

Example 1: Using type objects and character codes

Section titled “Example 1: Using type objects and character codes”
import numpy as np
# Using a NumPy type object
dt1 = np.dtype(np.int32)
print(f"dtype from np.int32: {dt1}")
# Using a character code string ('i4' = 4-byte integer)
dt2 = np.dtype('i4')
print(f"dtype from 'i4': {dt2}")
# Specifying big-endian byte order
dt3 = np.dtype('>i4') # '>' means big-endian
print(f"dtype with big-endian: {dt3}")

Output:

dtype from np.int32: int32
dtype from 'i4': int32
dtype with big-endian: >i4

Structured arrays allow you to define arrays where each element is like a C-style struct, containing multiple named fields, potentially with different data types. This is useful for representing heterogeneous data records within a NumPy array.

You define a structured dtype using a list of tuples, where each tuple is ('field_name', field_dtype).

Example 2: Defining and using a structured array

Section titled “Example 2: Defining and using a structured array”
import numpy as np
# Define a structured dtype for student records
# 'U20' = Unicode string of max length 20
# 'i1' = 1-byte integer (int8)
# 'f4' = 4-byte float (float32)
student_dtype = np.dtype([
('name', 'U20'),
('age', np.int8),
('marks', np.float32)
])
print(f"Structured dtype: {student_dtype}\n")
# Create an array using this structured dtype
students = np.array([
('Alice', 21, 85.5),
('Bob', 19, 92.0),
('Charlie', 22, 78.5)
], dtype=student_dtype)
print(f"Structured array:\n{students}\n")
# Access data by field name (returns a view, not a copy)
ages = students['age']
print(f"Ages: {ages}")
print(f"Type of 'ages': {type(ages)}")
print(f"dtype of 'ages': {ages.dtype}")
# Access data for a specific record
print(f"\nFirst student's name: {students[0]['name']}")

Output:

Structured dtype: [('name', '<U20'), ('age', 'i1'), ('marks', '<f4')]
Structured array:
[('Alice', 21, 85.5) ('Bob', 19, 92. ) ('Charlie', 22, 78.5)]
Ages: [21 19 22]
Type of 'ages': <class 'numpy.ndarray'>
dtype of 'ages': int8
First student's name: Alice

Note: While structured arrays are powerful, for general-purpose tabular data manipulation with heterogeneous types, the Pandas library (which builds on NumPy) and its DataFrame object are often more convenient and feature-rich.

For more detailed information, refer to the NumPy Data types documentation.