Typing (numpy.typing) — NumPy v2.6.dev0 Manual

Added in version 1.20.

Large parts of the NumPy API have

PEP 484

-style type annotations. In addition a number of type aliases are available to users, most prominently the two below:

ArrayLike

: objects that can be converted to arrays

DTypeLike

: objects that can be converted to dtypes

Differences from the runtime NumPy API

#

NumPy is very flexible. Trying to describe the full range of possibilities statically would result in types that are not very helpful. For that reason, the typed NumPy API is often stricter than the runtime NumPy API. This section describes some notable differences.

ArrayLike

#

The

ArrayLike

type tries to avoid creating object arrays. For example,

>>> np.array(x**2forxinrange(10))array(<generator object <genexpr> at ...>, dtype=object)is valid NumPy code which will create a 0-dimensional object array. Type checkers will complain about the above example when using the NumPy types however. If you really intended to do the above, then you can either use a #type:ignore comment:

>>> np.array(x**2forxinrange(10))# type: ignoreor explicitly type the array like object as

Any

:

>>> fromtypingimportAny>>> array_like:Any=(x**2forxinrange(10))>>> np.array(array_like)array(<generator object <genexpr> at ...>, dtype=object)DTypeLike

#

The

DTypeLike

type tries to avoid creation of dtype objects using dictionary of fields like below:

>>> x=np.dtype({"field1":(float,1),"field2":(int,3)})Although this is valid NumPy code, the type checker will complain about it, since its usage is discouraged. Please see :

Data type objects

Number precision

#

The precision of

numpy.number

subclasses is treated as an invariant generic parameter (see

NBitBase

), simplifying the annotating of processes involving precision-based casting.

>>> fromtypingimportTypeVar>>> importnumpyasnp>>> importnumpy.typingasnpt>>> T=TypeVar("T",bound=npt.NBitBase)>>> deffunc(a:np.floating[T],b:np.floating[T])->np.floating[T]:... ...Consequently, the likes of

float16

,

float32

and

float64

are still sub-types of

floating

, but, contrary to runtime, they’re not necessarily considered as sub-classes.

Deprecated since version 2.3: The

NBitBase

helper is deprecated and will be removed in a future release. Prefer expressing precision relationships via typing.overload or TypeVar definitions bounded by concrete scalar classes. For example:

fromtypingimportTypeVarimportnumpyasnpS=TypeVar("S",bound=np.floating)deffunc(a:S,b:S)->S:...or in the case of different input types mapping to different output types:

fromtypingimportoverloadimportnumpyasnp@overloaddefphase(x:np.complex64)->np.float32:...@overloaddefphase(x:np.complex128)->np.float64:...@overloaddefphase(x:np.clongdouble)->np.longdouble:...defphase(x:np.complexfloating)->np.floating:...Timedelta64

#

The

timedelta64

class is not considered a subclass of

signedinteger

, the former only inheriting from

generic

while static type checking.

Record array dtypes

#

The dtype of

numpy.recarray

, and the

Creating record arrays

functions in general, can be specified in one of two ways:

Directly via the dtype argument.

With up to five helper arguments that operate via

numpy.rec.format_parser

: formats, names, titles, aligned and byteorder.

These two approaches are currently typed as being mutually exclusive, i.e. if dtype is specified than one may not specify formats. While this mutual exclusivity is not (strictly) enforced during runtime, combining both dtype specifiers can lead to unexpected or even downright buggy behavior.

API

#

ndarray

The

numpy.ndarray

class is a

generic type

that accepts two type arguments:

The type of

numpy.ndarray.shape

, which must be a tuple of int, e.g. tuple[int,int] (2-D shape) or tuple[()] (0-D shape). The default shape is tuple[Any,...], which represents an unknown shape with any number of dimensions. Currently, Literal ints or other more specific types are not supported.

The type of

numpy.ndarray.dtype

, which must be a subtype of

numpy.dtype

such as numpy.dtype[numpy.float64]. If omitted, it will default to numpy.dtype[Any].

>>> importnumpyasnp>>> typeImageRGB=np.ndarray[tuple[int,int,int],np.dtype[np.uint8]]>>> typeVector[S:np.generic]=np.ndarray[tuple[int],np.dtype[S]]numpy.typing.ArrayLike=typing.Union[...]

#

A

Union

representing objects that can be coerced into an

ndarray

.

Among others this includes the likes of:

Scalars.

(Nested) sequences.

Objects implementing the __array__ protocol.

Added in version 1.20.

See Also

array_like

:Any scalar or sequence that can be interpreted as an ndarray.

Examples

>>> importnumpyasnp>>> importnumpy.typingasnpt>>> defas_array(a:npt.ArrayLike)->np.ndarray:... returnnp.array(a)

numpy.typing.DTypeLike=typing.Union[...]

#

A

Union

representing objects that can be coerced into a

dtype

.

Among others this includes the likes of:

type

objects.

Character codes or the names of

type

objects.

Objects with the .dtype attribute.

Added in version 1.20.

Examples

>>> importnumpyasnp>>> importnumpy.typingasnpt>>> defas_dtype(d:npt.DTypeLike)->np.dtype:... returnnp.dtype(d)numpy.typing.NDArray=NDArray

#

A

np.ndarray[tuple[Any, ...], np.dtype[ScalarT]]

type alias

generic

w.r.t. its

dtype.type

.

Can be used during runtime for typing arrays with a given dtype and unspecified shape.

Added in version 1.21.

Examples

>>> importnumpyasnp>>> importnumpy.typingasnpt>>> print(npt.NDArray)NDArray>>> print(npt.NDArray[np.float64])NDArray[numpy.float64]>>> NDArrayInt=npt.NDArray[np.int_]>>> a:NDArrayInt=np.arange(10)>>> deffunc(a:npt.ArrayLike)->npt.NDArray[Any]:... returnnp.array(a)classnumpy.typing.NBitBase

[source]

#

A type representing

numpy.number

precision during static type checking.

Used exclusively for the purpose of static type checking,

NBitBase

represents the base of a hierarchical set of subclasses. Each subsequent subclass is herein used for representing a lower level of precision, e.g.64Bit>32Bit>16Bit.

Added in version 1.20.

Deprecated since version 2.3: Use @typing.overload or a TypeVar with a scalar-type as upper bound, instead.

Examples

Below is a typical usage example:

NBitBase

is herein used for annotating a function that takes a float and integer of arbitrary precision as arguments and returns a new float of whichever precision is largest (e.g.np.float16+np.int64->np.float64).

>>> fromtypingimportTYPE_CHECKING>>> importnumpyasnp>>> importnumpy.typingasnpt>>> defadd[S:npt.NBitBase,T:npt.NBitBase](... a:np.floating[S],b:np.integer[T]... )->np.floating[S|T]:... returna+b>>> a=np.float16()>>> b=np.int64()>>> out=add(a,b)>>> ifTYPE_CHECKING:... reveal_locals()... # note: Revealed local types are:... # note: a: numpy.floating[numpy.typing._16Bit*]... # note: b: numpy.signedinteger[numpy.typing._64Bit*]... # note: out: numpy.floating[numpy.typing._64Bit*]