Python defines only one type of a particular data class (there is only one integer type, one floating-point type, etc.). This can be convenient in applications that don’t need to be concerned with all the ways data can be represented in a computer. For scientific computing, however, more control is often needed.
In NumPy, there are 24 new fundamental Python types to describe different types of scalars. These type descriptors are mostly based on the types available in the C language that CPython is written in, with several additional types compatible with Python’s types.
Array scalars have the same attributes and methods as ndarrays. 1 This allows one to treat items of an array partly on the same footing as arrays, smoothing out rough edges that result when mixing scalar and array operations.
ndarrays
Array scalars live in a hierarchy (see the Figure below) of data types. They can be detected using the hierarchy: For example, isinstance(val, np.generic) will return True if val is an array scalar object. Alternatively, what kind of array scalar is present can be determined using other members of the data type hierarchy. Thus, for example isinstance(val, np.complexfloating) will return True if val is a complex valued type, while isinstance(val, np.flexible) will return true if val is one of the flexible itemsize array types (str_, bytes_, void).
isinstance(val, np.generic)
True
isinstance(val, np.complexfloating)
isinstance(val, np.flexible)
str_
bytes_
void
Figure: Hierarchy of type objects representing the array data types. Not shown are the two integer types intp and uintp which just point to the integer type that holds a pointer for the platform. All the number types can be obtained using bit-width names as well.¶
intp
uintp
However, array scalars are immutable, so none of the array scalar attributes are settable.
The built-in scalar types are shown below. The C-like names are associated with character codes, which are shown in their descriptions. Use of the character codes, however, is discouraged.
Some of the scalar types are essentially equivalent to fundamental Python types and therefore inherit from them as well as from the generic array scalar type:
Array scalar type
Related Python type
Inherits?
int_
int
Python 2 only
float_
float
yes
complex_
complex
bytes
str
bool_
bool
no
datetime64
datetime.datetime
timedelta64
datetime.timedelta
The bool_ data type is very similar to the Python bool but does not inherit from it because Python’s bool does not allow itself to be inherited from, and on the C-level the size of the actual bool data is not the same as a Python Boolean scalar.
Warning
The int_ type does not inherit from the int built-in under Python 3, because type int is no longer a fixed-width integer type.
Tip
The default data type in NumPy is float_.
numpy.
generic
Base class for numpy scalar types.
Class from which most (all?) numpy scalar types are derived. For consistency, exposes the same API as ndarray, despite many consequent attributes being either “get-only,” or completely irrelevant. This is the class from which it is strongly suggested users should derive custom scalar types.
ndarray
number
Abstract base class of all numeric scalar types.
integer
Abstract base class of all integer scalar types.
signedinteger
Abstract base class of all signed integer scalar types.
byte
Signed integer type, compatible with C char.
char
'b'
numpy.int8: 8-bit signed integer (-128 to 127).
numpy.int8
-128
127
short
Signed integer type, compatible with C short.
'h'
numpy.int16: 16-bit signed integer (-32_768 to 32_767).
numpy.int16
-32_768
32_767
intc
Signed integer type, compatible with C int.
'i'
numpy.int32: 32-bit signed integer (-2_147_483_648 to 2_147_483_647).
numpy.int32
-2_147_483_648
2_147_483_647
Signed integer type, compatible with Python int and C long.
long
'l'
numpy.int64: 64-bit signed integer (-9_223_372_036_854_775_808 to 9_223_372_036_854_775_807).
numpy.int64
-9_223_372_036_854_775_808
9_223_372_036_854_775_807
numpy.intp: Signed integer large enough to fit pointer, compatible with C intptr_t.
numpy.intp
intptr_t
longlong
Signed integer type, compatible with C long long.
long long
'q'
unsignedinteger
Abstract base class of all unsigned integer scalar types.
ubyte
Unsigned integer type, compatible with C unsigned char.
unsigned char
'B'
numpy.uint8: 8-bit unsigned integer (0 to 255).
numpy.uint8
0
255
ushort
Unsigned integer type, compatible with C unsigned short.
unsigned short
'H'
numpy.uint16: 16-bit unsigned integer (0 to 65_535).
numpy.uint16
65_535
uintc
Unsigned integer type, compatible with C unsigned int.
unsigned int
'I'
numpy.uint32: 32-bit unsigned integer (0 to 4_294_967_295).
numpy.uint32
4_294_967_295
uint
Unsigned integer type, compatible with C unsigned long.
unsigned long
'L'
numpy.uint64: 64-bit unsigned integer (0 to 18_446_744_073_709_551_615).
numpy.uint64
18_446_744_073_709_551_615
numpy.uintp: Unsigned integer large enough to fit pointer, compatible with C uintptr_t.
numpy.uintp
uintptr_t
ulonglong
Signed integer type, compatible with C unsigned long long.
unsigned long long
'Q'
inexact
Abstract base class of all numeric scalar types with a (potentially) inexact representation of the values in its range, such as floating-point numbers.
floating
Abstract base class of all floating-point scalar types.
half
Half-precision floating-point number type.
'e'
numpy.float16: 16-bit-precision floating-point number type: sign bit, 5 bits exponent, 10 bits mantissa.
numpy.float16
single
Single-precision floating-point number type, compatible with C float.
'f'
numpy.float32: 32-bit-precision floating-point number type: sign bit, 8 bits exponent, 23 bits mantissa.
numpy.float32
double
Double-precision floating-point number type, compatible with Python float and C double.
'd'
numpy.float_
numpy.float64: 64-bit precision floating-point number type: sign bit, 11 bits exponent, 52 bits mantissa.
numpy.float64
longdouble
Extended-precision floating-point number type, compatible with C long double but not necessarily with IEEE 754 quadruple-precision.
long double
'g'
numpy.longfloat
numpy.float128: 128-bit extended-precision floating-point number type.
numpy.float128
complexfloating
Abstract base class of all complex number scalar types that are made up of floating-point numbers.
csingle
Complex number type composed of two single-precision floating-point numbers.
'F'
numpy.singlecomplex
numpy.complex64: Complex number type composed of 2 32-bit-precision floating-point numbers.
numpy.complex64
cdouble
Complex number type composed of two double-precision floating-point numbers, compatible with Python complex.
'D'
numpy.cfloat
numpy.complex_
numpy.complex128: Complex number type composed of 2 64-bit-precision floating-point numbers.
numpy.complex128
clongdouble
Complex number type composed of two extended-precision floating-point numbers.
'G'
numpy.clongfloat
numpy.longcomplex
numpy.complex256: Complex number type composed of 2 128-bit extended-precision floating-point numbers.
numpy.complex256
Boolean type (True or False), stored as a byte.
The bool_ type is not a subclass of the int_ type (the bool_ is not even a number type). This is different than Python’s default implementation of bool as a sub-class of int.
'?'
numpy.bool8
A datetime stored as a 64-bit integer, counting from 1970-01-01T00:00:00.
1970-01-01T00:00:00
>>> np.datetime64(10, 'Y') numpy.datetime64('1980') >>> np.datetime64(10, 'D') numpy.datetime64('1970-01-11')
See Datetimes and Timedeltas for more information.
'M'
A timedelta stored as a 64-bit integer.
'm'
object_
Any Python object.
'O'
Note
The data actually stored in object arrays (i.e., arrays having dtype object_) are references to Python objects, not the objects themselves. Hence, object arrays behave more like usual Python lists, in the sense that their contents need not be of the same Python type.
lists
The object type is also special because an array containing object_ items does not return an object_ object on item access, but instead returns the actual object that the array item refers to.
The following data types are flexible: they have no predefined size and the data they describe can be of different length in different arrays. (In the character codes # is an integer denoting how many elements the data type consists of.)
#
flexible
Abstract base class of all scalar types without predefined length. The actual size of these types depends on the specific np.dtype instantiation.
A byte string.
When used in arrays, this type strips trailing null bytes.
'S'
numpy.string_
A unicode string.
When used in arrays, this type strips trailing null codepoints.
Unlike the builtin str, this supports the Buffer Protocol, exposing its contents as UCS4:
>>> m = memoryview(np.str_("abc")) >>> m.format '3w' >>> m.tobytes() b'a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00'
'U'
numpy.unicode_
Either an opaque sequence of bytes, or a structure.
>>> np.void(b'abcd') void(b'\x61\x62\x63\x64')
Structured void scalars can only be constructed via extraction from Structured arrays:
>>> arr = np.array((1, 2), dtype=[('x', np.int8), ('y', np.int8)]) >>> arr[()] (1, 2) # looks like a tuple, but is `np.void`
'V'
See Note on string types.
Numeric Compatibility: If you used old typecode characters in your Numeric code (which was never recommended), you will need to change some of them to the new characters. In particular, the needed changes are c -> S1, b -> B, 1 -> b, s -> h, w -> H, and u -> I. These changes make the type character convention more consistent with other Python modules such as the struct module.
c -> S1
b -> B
1 -> b
s -> h
w -> H
u -> I
struct
Along with their (mostly) C-derived names, the integer, float, and complex data-types are also available using a bit-width convention so that an array of the right size can always be ensured. Two aliases (numpy.intp and numpy.uintp) pointing to the integer type that is sufficiently large to hold a C pointer are also provided.
bool8
alias of numpy.bool_
numpy.bool_
int8
int16
int32
int64
Aliases for the signed integer types (one of numpy.byte, numpy.short, numpy.intc, numpy.int_ and numpy.longlong) with the specified number of bits.
numpy.byte
numpy.short
numpy.intc
numpy.int_
numpy.longlong
Compatible with the C99 int8_t, int16_t, int32_t, and int64_t, respectively.
int8_t
int16_t
int32_t
int64_t
uint8
uint16
uint32
uint64
Alias for the unsigned integer types (one of numpy.byte, numpy.short, numpy.intc, numpy.int_ and numpy.longlong) with the specified number of bits.
Compatible with the C99 uint8_t, uint16_t, uint32_t, and uint64_t, respectively.
uint8_t
uint16_t
uint32_t
uint64_t
Alias for the signed integer type (one of numpy.byte, numpy.short, numpy.intc, numpy.int_ and np.longlong) that is the same size as a pointer.
Compatible with the C intptr_t.
'p'
Alias for the unsigned integer type (one of numpy.byte, numpy.short, numpy.intc, numpy.int_ and np.longlong) that is the same size as a pointer.
Compatible with the C uintptr_t.
'P'
float16
alias of numpy.half
numpy.half
float32
alias of numpy.single
numpy.single
float64
alias of numpy.double
numpy.double
float96
float128
Alias for numpy.longdouble, named after its size in bits. The existence of these aliases depends on the platform.
numpy.longdouble
complex64
alias of numpy.csingle
numpy.csingle
complex128
alias of numpy.cdouble
numpy.cdouble
complex192
complex256
Alias for numpy.clongdouble, named after its size in bits. The existance of these aliases depends on the platform.
numpy.clongdouble
The first two of these are conveniences which resemble the names of the builtin types, in the same style as bool_, int_, str_, bytes_, and object_:
Some more use alternate naming conventions for extended-precision floats and complex numbers:
longfloat
alias of numpy.longdouble
singlecomplex
cfloat
longcomplex
alias of numpy.clongdouble
clongfloat
The following aliases originate from Python 2, and it is recommended that they not be used in new code.
string_
alias of numpy.bytes_
numpy.bytes_
unicode_
alias of numpy.str_
numpy.str_
The array scalar objects have an array priority of NPY_SCALAR_PRIORITY (-1,000,000.0). They also do not (yet) have a ctypes attribute. Otherwise, they share the same attributes as arrays:
array priority
NPY_SCALAR_PRIORITY
ctypes
generic.flags
The integer value of flags.
generic.shape
Tuple of array dimensions.
generic.strides
Tuple of bytes steps in each dimension.
generic.ndim
The number of array dimensions.
generic.data
Pointer to start of data.
generic.size
The number of elements in the gentype.
generic.itemsize
The length of one element in bytes.
generic.base
Scalar attribute identical to the corresponding array attribute.
generic.dtype
Get array data-descriptor.
generic.real
The real part of the scalar.
generic.imag
The imaginary part of the scalar.
generic.flat
A 1-D view of the scalar.
generic.T
generic.__array_interface__
Array protocol: Python side
generic.__array_struct__
Array protocol: struct
generic.__array_priority__
Array priority.
generic.__array_wrap__
sc.__array_wrap__(obj) return scalar from array
See also
Indexing, Data type objects (dtype)
Array scalars can be indexed like 0-dimensional arrays: if x is an array scalar,
x[()] returns a copy of array scalar
x[()]
x[...] returns a 0-dimensional ndarray
x[...]
x['field-name'] returns the array scalar in the field field-name. (x can have fields, for example, when it corresponds to a structured data type.)
x['field-name']
Array scalars have exactly the same methods as arrays. The default behavior of these methods is to internally convert the scalar to an equivalent 0-dimensional array and to call the corresponding array method. In addition, math operations on array scalars are defined so that the same hardware flags are set and used to interpret the results as for ufunc, so that the error state used for ufuncs also carries over to the math on array scalars.
The exceptions to the above rules are given below:
generic.__array__
sc.__array__(dtype) return 0-dim array from scalar with specified dtype
generic.squeeze
Scalar method identical to the corresponding array attribute.
generic.byteswap
generic.__reduce__
Helper for pickle.
generic.__setstate__
generic.setflags
There are two ways to effectively define a new array scalar type (apart from composing structured types dtypes from the built-in scalar types): One way is to simply subclass the ndarray and overwrite the methods of interest. This will work to a degree, but internally certain behaviors are fixed by the data type of the array. To fully customize the data type of an array you need to define a new data-type, and register it with NumPy. Such new types can only be defined in C, using the NumPy C-API.