In this Python tutorial, we will take a look into the Python NumPy module. This tutorial will discuss and show examples of the NumPy basics with a discussion on NumPy architecture and the environment. This tutorial will introduce the basics of NumPy with examples that are used in data science and machine learning.

## Python NumPy Module

The NumPy module means Numerical Python and consists of multidimensional array objects and processes those arrays with a a collection of routines. These arrays are able to have logical and mathematical operations performed on the created arrays by using NumPy. The Python package NumPy is a fundamental package that has the unique capabilities for scientific computing. In addition, it offers the below as well:

- N-dimensional array object
- Sophisticated functions
- Random number capabilities, useful for linear algebra, and Fourier transform

Besides the obvious scientific uses, NumPy also offers an efficient multi-dimensional container of generic data. This allows arbitrary data-types can be defined and will NumPy to speedily and efficiently integrate with a wide variety of databases.

## NumPy Basic Functions

The main object in NumPy is homogeneous multi-dimensional array, which are elements (mostly numbers) of all the same type. The dimensions in NumPy are called axes. An array in NumPy is called a ndarray and is known by the name array. The Python array and NumPy array are not the same. The Python array only handles arrays in one-dimension with less functionality.

### NumPy Array Objects

Below are a list of objects to execute on a NumPy array with examples.

**ndarray.ndim**: Provides the number of axes (dimensions) of the array.**ndarray.shape**: Provides the dimensions of the array.**ndarray.size**: Provides the total number of elements of the array. This is equal to the product of the elements of shape.**ndarray.dtype**: This is an object describing the type of the elements in the array. One can create or specify dtype’s using standard Python types. NumPy provides additional types: numpy.int32, numpy.int16, and numpy.float64 are a few examples.**ndarray.itemsize**: Provides the size in bytes of each element of the array.**ndarray.data**: The buffer containing the actual elements of the array. This attribute usually does not need to use this because another option is using the indexing facilities from the elements in an array.

**Input:**

1 2 3 4 5 6 7 8 9 |
import numpy as np numbers = np.arange(50).reshape(5, 10) print(f"numbers.ndim: {numbers.ndim} ") print(f"numbers.shape: {numbers.shape} ") print(f"numbers.size: {numbers.size} ") print(f"numbers.dtype: {numbers.dtype} ") print(f"numbers.itemsize: {numbers.itemsize} ") |

**Output:**

1 2 3 4 5 |
numbers.ndim: 2 numbers.shape: (5, 10) numbers.size: 50 numbers.dtype: int32 numbers.itemsize: 4 |

## Python Array and NumPy Array

Let’s take a quick look at a basic array in Python and a NumPy array. When trying to print an array, NumPy will display similar to nested Python lists:

- The last axis is printed from left to right
- The second-to-last is printed from top to bottom,
- The remainder printed from top to bottom, with each slice separated from the next by an empty line

Bi-dimensionals as matrices and tri-dimensionals as lists of matrices and one-dimensional arrays are then printed as rows.

**Input:**

1 2 3 4 5 6 7 8 |
import numpy as np py_array = [1,2,3,4,5,6,7,8,9] # numpy array numpy_array = np.array([1,2,3,4,5,6,7,8,9]) print(f"Python array: {py_array} ") print(f"NumPy array: {numpy_array} ")) |

**Output:**

1 2 |
Python array: [1, 2, 3, 4, 5, 6, 7, 8, 9] NumPy array: [1 2 3 4 5 6 7 8 9] |

## NumPy Arrange

The NumPy arrange function allows the creation of a simple list of numbers by prompting the start, stop and step within the function as such: (0,25,5)

**Input:**

1 2 |
numpy_arrange = np.arange(0,30,6) print(f"Numpy arrange: {numpy_arrange} ") |

**Output:**

1 |
Numpy arrange: [ 0 6 12 18 24] |

## NumPy Shape and Reshape

Shape is another attribute for a NumPy array and reshape is a method that will change the dimensions of the matrix into a new dimension that’s specified. By doing so, we will pass a tuple of any dimension with the same number of elements as the original matrix.

**Input:**

1 2 3 4 5 6 7 |
import numpy as np numpy_array = np.array([1,2,3,4,5,6,7,8,9]) numpy_reshape = numpy_array.reshape(1,9) print(f"numbers.shape: {numpy_array.shape} ") print(f"numbers.reshape: {numpy_reshape} ") |

**Output:**

1 2 |
numbers.shape: (9,) numbers.reshape: [[1 2 3 4 5 6 7 8 9]] |

## NumPy Sum

The NumPy sum attribute will add all elements in the NumPy array.

**Input:**

1 2 3 4 5 |
import numpy as np numpy_sum = numpy_array.sum() print(f"Sum of numpy_array: {numpy_sum} ") |

**Output:**

1 |
Sum of numpy_array: 45 |

## Python Range and NumPy Arange Timing

NumPy provides a major advantage of timing to complete a function when compared to a standard Python function. Below is an example of executing a Python **range()** function and the NumPy **arange()** function.

**Input:**

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from timeit import Timer import numpy as np size = 1000 list1 = range(size) list2 = range(size) n_arange1 = np.arange(size) n_arange2 = np.arange(size) def python_function(): list3 = [list1[i] + list2[i] for i in range(len(list1)) ] def numpy_function(): list3 = n_arange1 + n_arange2 timer1 = Timer("python_function()", "from __main__ import python_function") timer2 = Timer("numpy_function()", "from __main__ import numpy_function") print(f"Python function time: {timer1.timeit(10)} ") print(f"NumPy function time: {timer2.timeit(10)} ") |

**Output:**

1 2 |
Python function time: 0.004237329000000067 NumPy function time: 0.00011688900000006441 |

I hope this Python tutorial on NumPy provided knowledge on the basic functions used in NumPy.