Now that we know how to create a vector, we are ready to create a multidimensional NumPy array. After we create the matrix, we would again want to display its shape.
In: m = array([arange(2), arange(2)]) In: m Out: array([[0, 1], [0, 1]]) In: m.shape Out: (2, 2)
We created a two-by-two array with the arange
function we have come to trust and love. Without any warning, the array
function appeared on the stage.
The array
function creates an array from an object that you give to it. The object needs to be array-like, for instance, a Python list. In the preceding example, we passed in a list of arrays. The object is the only required argument of the array
function. NumPy functions tend to have a lot of optional arguments with predefined defaults.
Q1. How is the shape of an ndarray
stored?
It shouldn't be too hard now to create a three-by-three matrix. Give it a go and check whether the array shape is as expected.
From time to time, we will want to select a particular element of an array. We will take a look at how to do this, but first, let's create a two-by-two matrix again:
In: a = array([[1,2],[3,4]]) In: a Out: array([[1, 2], [3, 4]])
The matrix was created this time by passing the array
function a list of lists. We will now select each item of the matrix one-by-one. Remember, the indices are numbered starting from 0
.
In: a[0,0] Out: 1 In: a[0,1] Out: 2 In: a[1,0] Out: 3 In: a[1,1] Out: 4
As you can see, selecting elements of the array is pretty simple. For the array a
, we just use the notation a[m,n]
, where m
and n
are the indices of the item in the array as shown in the following diagram:
Python has an integer type, a float type, and a complex type, however, this is not enough for scientific computing and, for this reason, NumPy has a lot more data types. In practice, we need even more types with varying precision and, therefore, different memory size of the type. The majority of the NumPy numerical types end with a number. This number indicates the number of bits associated with the type. The following table (adapted from the NumPy user guide) gives an overview of NumPy numerical types:
For each data type, there exists a corresponding conversion function:
In: float64(42) Out: 42.0 In: int8(42.0) Out: 42 In: bool(42) Out: True In: bool(0) Out: False In: bool(42.0) Out: True In: float(True) Out: 1.0 In: float(False) Out: 0.0
Many functions have a data type argument, which is often optional:
In: arange(7, dtype=uint16) Out: array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)
It is important to know that you are not allowed to convert a complex number into an integer. Trying to do that triggers a TypeError:
The same goes for conversion of a complex number into a float. By the way, the j
part is the imaginary coefficient of the complex number. However, you can convert a float to a complex number, for instance complex(1.0)
.
Data type objects are instances of the numpy.dtype
class. Once again, arrays have a data type. To be precise, every element in a NumPy array has the same data type. The data type object can tell you the size of the data in bytes. The size in bytes is given by the itemsize
attribute of the dtype
class:
In: a.dtype.itemsize Out: 8
Character codes are included for backward compatibility with Numeric. Numeric is the predecessor of NumPy. Their use is not recommended, but the codes are provided here because they pop up in several places. You should instead use dtype
objects.
Type |
Character code |
---|---|
integer |
|
Unsigned integer |
|
Single precision float |
|
Double precision float |
|
bool |
|
complex |
|
string |
|
unicode |
|
Void |
|
Look at the following code to create an array of single precision floats:
In: arange(7, dtype='f') Out: array([ 0., 1., 2., 3., 4., 5., 6.], dtype=float32) Likewise this creates an array of complex numbers In: arange(7, dtype='D') Out: array([ 0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j])
We have a variety of ways to create data types. Take the case of floating point data:
In: dtype(float) Out: dtype('float64')
In: dtype('f') Out: dtype('float32')
In: dtype('d') Out: dtype('float64')
In: dtype('f8') Out: dtype('float64')
A listing of all full data type names can be found in sctypeDict.keys()
:
In: sctypeDict.keys() Out: [0, … 'i2', 'int0']
The dtype
class has a number of useful attributes. For example, we can get information about the character code of a data type through the attributes of dtype
:
In: t = dtype('Float64') In: t.char Out: 'd'
The type attribute corresponds to the type of object of the array elements:
In: t.type Out: <type 'numpy.float64'>
The str
attribute of dtype
gives a string representation of the data type. It starts with a character representing endianness, if appropriate, then a character code, followed by a number corresponding to the number of bytes that each array item requires. Endianness, here, means the way bytes are ordered within a 32 or 64-bit word. In big-endian order, the most significant byte is stored first; indicated by >
. In little-endian order, the least significant byte is stored first; indicated by <
:
In: t.str Out: '<f8'