Python defines only one type of a particular data class (there is onlyone integer type, one floating-point type, etc.). This can beconvenient in applications that don’t need to be concerned with allthe ways data can be represented in a computer. For scientificcomputing, however, more control is often needed.
In NumPy, there are 24 new fundamental Python types to describedifferent types of scalars. These type descriptors are mostly based onthe types available in the C language that CPython is written in, withseveral additional types compatible with Python’s types.
Array scalars have the same attributes and methods asndarrays.[1] This allows one to treat items of an array partly onthe same footing as arrays, smoothing out rough edges that result whenmixing scalar and array operations.
Array scalars live in a hierarchy (see the Figure below) of datatypes. They can be detected using the hierarchy: For example,isinstance(val,np.generic) will returnTrue ifval isan array scalar object. Alternatively, what kind of array scalar ispresent can be determined using other members of the data typehierarchy. Thus, for exampleisinstance(val,np.complexfloating)will returnTrue ifval is a complex valued type, whileisinstance(val,np.flexible) will return true ifval is oneof the flexible itemsize array types (string,unicode,void).

Figure: Hierarchy of type objects representing the array datatypes. Not shown are the two integer typesintp anduintp which just point to the integer type that holds apointer for the platform. All the number types can be obtainedusing bit-width names as well.
| [1] | However, array scalars are immutable, so none of the arrayscalar attributes are settable. |
The built-in scalar types are shown below. Along with their (mostly)C-derived names, the integer, float, and complex data-types are alsoavailable using a bit-width convention so that an array of the rightsize can always be ensured (e.g.int8,float64,complex128). Two aliases (intp anduintp)pointing to the integer type that is sufficiently large to hold a C pointerare also provided. The C-like names are associated with character codes,which are shown in the table. Use of the character codes, however,is discouraged.
Some of the scalar types are essentially equivalent to fundamentalPython types and therefore inherit from them as well as from thegeneric array scalar type:
| Array scalar type | Related Python type |
|---|---|
int_ | IntType (Python 2 only) |
float_ | FloatType |
complex_ | ComplexType |
bytes_ | BytesType |
unicode_ | UnicodeType |
Thebool_ data type is very similar to the PythonBooleanType but does not inherit from it because Python’sBooleanType does not allow itself to be inherited from, andon the C-level the size of the actual bool data is not the same as aPython Boolean scalar.
Warning
Thebool_ type is not a subclass of theint_ type(thebool_ is not even a number type). This is differentthan Python’s default implementation ofbool as asub-class of int.
Warning
Theint_ type doesnot inherit from theint built-in under Python 3, because typeint is nolonger a fixed-width integer type.
Tip
The default data type in NumPy isfloat_.
In the tables below,platform? means that the type may not beavailable on all platforms. Compatibility with different C or Pythontypes is indicated: two types are compatible if their data is of thesame size and interpreted in the same way.
Booleans:
| Type | Remarks | Character code |
|---|---|---|
bool_ | compatible: Python bool | '?' |
bool8 | 8 bits |
Integers:
byte | compatible: C char | 'b' |
short | compatible: C short | 'h' |
intc | compatible: C int | 'i' |
int_ | compatible: Python int | 'l' |
longlong | compatible: C long long | 'q' |
intp | large enough to fit a pointer | 'p' |
int8 | 8 bits | |
int16 | 16 bits | |
int32 | 32 bits | |
int64 | 64 bits |
Unsigned integers:
ubyte | compatible: C unsigned char | 'B' |
ushort | compatible: C unsigned short | 'H' |
uintc | compatible: C unsigned int | 'I' |
uint | compatible: Python int | 'L' |
ulonglong | compatible: C long long | 'Q' |
uintp | large enough to fit a pointer | 'P' |
uint8 | 8 bits | |
uint16 | 16 bits | |
uint32 | 32 bits | |
uint64 | 64 bits |
Floating-point numbers:
half | 'e' | |
single | compatible: C float | 'f' |
double | compatible: C double | |
float_ | compatible: Python float | 'd' |
longfloat | compatible: C long float | 'g' |
float16 | 16 bits | |
float32 | 32 bits | |
float64 | 64 bits | |
float96 | 96 bits, platform? | |
float128 | 128 bits, platform? |
Complex floating-point numbers:
csingle | 'F' | |
complex_ | compatible: Python complex | 'D' |
clongfloat | 'G' | |
complex64 | two 32-bit floats | |
complex128 | two 64-bit floats | |
complex192 | two 96-bit floats,platform? | |
complex256 | two 128-bit floats,platform? |
Any Python object:
object_ | any Python object | 'O' |
Note
The data actually stored inobject arrays(i.e., arrays having dtypeobject_) are references toPython objects, not the objects themselves. Hence, object arraysbehave more like usual Pythonlists, in the sensethat their contents need not be of the same Python type.
The object type is also special because an array containingobject_ items does not return anobject_ objecton item access, but instead returns the actual object thatthe array item refers to.
The following data types areflexible. They have no predefinedsize: the data they describe can be of different length in differentarrays. (In the character codes# is an integer denoting how manyelements the data type consists of.)
bytes_ | compatible: Python bytes | 'S#' |
unicode_ | compatible: Python unicode/str | 'U#' |
void | 'V#' |
Warning
Numeric Compatibility: If you used old typecode characters in yourNumeric code (which was never recommended), you will need to changesome of them to the new characters. In particular, the neededchanges arec->S1,b->B,1->b,s->h,w->H, andu->I. These changes make the type characterconvention more consistent with other Python modules such as thestruct module.
The array scalar objects have anarraypriority ofNPY_SCALAR_PRIORITY(-1,000,000.0). They also do not (yet) have actypesattribute. Otherwise, they share the same attributes as arrays:
generic.flags | integer value of flags |
generic.shape | tuple of array dimensions |
generic.strides | tuple of bytes steps in each dimension |
generic.ndim | number of array dimensions |
generic.data | pointer to start of data |
generic.size | number of elements in the gentype |
generic.itemsize | length of one element in bytes |
generic.base | base object |
generic.dtype | get array data-descriptor |
generic.real | real part of scalar |
generic.imag | imaginary part of scalar |
generic.flat | a 1-d view of scalar |
generic.T | transpose |
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
Array scalars can be indexed like 0-dimensional arrays: ifx is anarray scalar,
x[()] returns a copy of array scalarx[...] returns a 0-dimensionalndarrayx['field-name'] returns the array scalar in the fieldfield-name.(x can have fields, for example, when it corresponds to a structured data type.)Array scalars have exactly the same methods as arrays. The defaultbehavior of these methods is to internally convert the scalar to anequivalent 0-dimensional array and to call the corresponding arraymethod. In addition, math operations on array scalars are defined sothat the same hardware flags are set and used to interpret the resultsas forufunc, so that the error state used for ufuncsalso carries over to the math on array scalars.
The exceptions to the above rules are given below:
generic | Base class for numpy scalar types. |
generic.__array__ | sc.__array__(dtype) return 0-dim array from scalar with specified dtype |
generic.__array_wrap__ | sc.__array_wrap__(obj) return scalar from array |
generic.squeeze | Not implemented (virtual attribute) |
generic.byteswap | Not implemented (virtual attribute) |
generic.__reduce__ | |
generic.__setstate__ | |
generic.setflags | Not implemented (virtual attribute) |
There are two ways to effectively define a new array scalar type(apart from composing structured typesdtypes fromthe built-in scalar types): One way is to simply subclass thendarray and overwrite the methods of interest. This will work toa degree, but internally certain behaviors are fixed by the data type ofthe array. To fully customize the data type of an array you need todefine a new data-type, and register it with NumPy. Such new types can onlybe defined in C, using theNumPy C-API.