Files
labs/Module-2/5.Numpy/2-Understanding-Data-Types.ipynb

11 KiB

Understanding Data Types in Python

A Python List Is More Than Just a List

Let's consider now what happens when we use a Python data structure that holds many Python objects. The standard mutable multielement container in Python is the list. We can create a list of integers as follows:

In [ ]:
L = list(range(10))
L
In [ ]:
type(L[0])

Or, similarly, a list of strings:

In [ ]:
L2 = [str(c) for c in L]
L2
In [ ]:
type(L2[0])

Because of Python's dynamic typing, we can even create heterogeneous lists:

In [ ]:
L3 = [True, "2", 3.0, 4]
[type(item) for item in L3]

Fixed-Type Arrays in Python

In [ ]:
import array
L = list(range(10))
A = array.array('i', L)
A

Here, 'i' is a type code indicating the contents are integers.

Much more useful, however, is the ndarray object of the NumPy package. While Python's array object provides efficient storage of array-based data, NumPy adds to this efficient operations on that data. We will explore these operations in later chapters; next, I'll show you a few different ways of creating a NumPy array.

Creating Arrays from Python Lists

We'll start with the standard NumPy import, under the alias np:

In [ ]:
import numpy as np

Now we can use np.array to create arrays from Python lists:

In [ ]:
# Integer array
np.array([1, 4, 2, 5, 3])

Remember that unlike Python lists, NumPy arrays can only contain data of the same type. If the types do not match, NumPy will upcast them according to its type promotion rules; here, integers are upcast to floating point:

In [ ]:
np.array([3.14, 4, 2, 3])

If we want to explicitly set the data type of the resulting array, we can use the dtype keyword:

In [ ]:
np.array([1, 2, 3, 4], dtype=np.float32)

Finally, unlike Python lists, which are always one-dimensional sequences, NumPy arrays can be multidimensional. Here's one way of initializing a multidimensional array using a list of lists:

In [ ]:
# Nested lists result in multidimensional arrays
np.array([range(i, i + 3) for i in [2, 4, 6]])

The inner lists are treated as rows of the resulting two-dimensional array.

Creating Arrays from Scratch

Especially for larger arrays, it is more efficient to create arrays from scratch using routines built into NumPy. Here are several examples:

In [ ]:
# Create a length-10 integer array filled with 0s
np.zeros(10, dtype=int)
In [ ]:
# Create a 3x5 floating-point array filled with 1s
np.ones((3, 5), dtype=float)
In [ ]:
# Create a 3x5 array filled with 3.14
np.full((3, 5), 3.14)
In [ ]:
# Create an array filled with a linear sequence
# starting at 0, ending at 20, stepping by 2
# (this is similar to the built-in range function)
np.arange(0, 20, 2)
In [ ]:
# Create an array of five values evenly spaced between 0 and 1
np.linspace(0, 1, 5)
In [ ]:
# Create a 3x3 array of uniformly distributed
# pseudorandom values between 0 and 1
np.random.random((3, 3))
In [ ]:
# Create a 3x3 array of normally distributed pseudorandom
# values with mean 0 and standard deviation 1
np.random.normal(0, 1, (3, 3))
In [ ]:
# Create a 3x3 array of pseudorandom integers in the interval [0, 10)
np.random.randint(0, 10, (3, 3))
In [ ]:
# Create a 3x3 identity matrix
np.eye(3)
In [ ]:
# Create an uninitialized array of three integers; the values will be
# whatever happens to already exist at that memory location
np.empty(3)

NumPy Standard Data Types

NumPy arrays contain values of a single type, so it is important to have detailed knowledge of those types and their limitations. Because NumPy is built in C, the types will be familiar to users of C, Fortran, and other related languages.

The standard NumPy data types are listed in the following table. Note that when constructing an array, they can be specified using a string:

np.zeros(10, dtype='int16')

Or using the associated NumPy object:

np.zeros(10, dtype=np.int16)
Data type Description
bool_ Boolean (True or False) stored as a byte
int_ Default integer type (same as C long; normally either int64 or int32)
intc Identical to C int (normally int32 or int64)
intp Integer used for indexing (same as C ssize_t; normally either int32 or int64)
int8 Byte (–128 to 127)
int16 Integer (–32768 to 32767)
int32 Integer (–2147483648 to 2147483647)
int64 Integer (–9223372036854775808 to 9223372036854775807)
uint8 Unsigned integer (0 to 255)
uint16 Unsigned integer (0 to 65535)
uint32 Unsigned integer (0 to 4294967295)
uint64 Unsigned integer (0 to 18446744073709551615)
float_ Shorthand for float64
float16 Half-precision float: sign bit, 5 bits exponent, 10 bits mantissa
float32 Single-precision float: sign bit, 8 bits exponent, 23 bits mantissa
float64 Double-precision float: sign bit, 11 bits exponent, 52 bits mantissa
complex_ Shorthand for complex128
complex64 Complex number, represented by two 32-bit floats
complex128 Complex number, represented by two 64-bit floats