NUMPY - NUMerical PYthon

Today I learnt about NumPy: A library for numerical computations for Python

·

9 min read

NUMPY - NUMerical PYthon

NumPy (Numerical Python) is an open-source Python library that’s used in almost every field of science and engineering. It’s the universal standard for working with numerical data in Python, and it’s at the core of the scientific Python and PyData ecosystems.

The NumPy API is used extensively in Pandas, SciPy, Matplotlib, sci-kit-learn, sci-kit-image and most other data science and scientific Python packages.

  1. It provides ndarray, a homogeneous n-dimensional array object, with methods to efficiently operate on it.

  2. It adds powerful data structures to Python that guarantee efficient calculations with arrays and matrices and it supplies an enormous library of high-level mathematical functions that operate on these arrays and matrices.

Installing NumPy

conda install numpy

or

pip install numpy

Importing NumPy

import numpy as np

Difference between a Python list and a NumPy array?

NumPy gives you an enormous range of fast and efficient ways of creating arrays and manipulating numerical data inside them. While a Python list can contain different data types within a single list, all of the elements in a NumPy array should be homogeneous. The mathematical operations that are meant to be performed on arrays would be extremely inefficient if the arrays weren’t homogeneous..

  1. An array consumes less memory and is convenient to use.

What is an array?

An array is a central data structure of the NumPy library. An array is a grid of values and it contains information about the raw data, how to locate an element, and how to interpret an element.

Other:

The rank of the array is the number of dimensions. The shape of the array is a tuple of integers giving the size of the array along each dimension.

print(a[0])

What are the attributes of an array?

An array is usually a fixed-size container of items of the same type and size. The number of dimensions and items in an array is defined by its shape. The shape of an array is a tuple of non-negative integers that specify the sizes of each dimension

dimensions are called axes

Array attributes reflect information intrinsic to the array itself. If you need to get, or even set, properties of an array without creating a new array, you can often access an array through its attributes.

How to create a Basic array?

  1. np.array()

  2. np.zeros()

  3. np.ones()

  4. np.empty()

  5. np.arange()

  6. np..linspace()

  7. dtype

You can also use np.linspace() to create an array with values that are spaced linearly in a specified interval.

dtype=np.int64

Adding, removing, and sorting elements

  1. np.sort()

  2. np.concatenate()

In addition to sort, which returns a sorted copy of an array, you can use:

How to know the shape and size of an array?

  1. ndarray.ndim

  2. ndarray.size

  3. nadarray.shape

ndarray.ndim will tell you the number of axes, or dimensions, of the array.

ndarray.size will tell you the total number of elements of the array. This is the product of the elements of the array’s shape.

ndarray.shape will display a tuple of integers that indicate the number of elements stored along each dimension of the array. If, for example, you have a 2-D array with 2 rows and 3 columns, the shape of your array is (2, 3).

Can you reshape an array?

  1. arr.reshape()

Using arr.reshape() will give a new shape to an array without changing the data. Just remember that when you use the reshape method, the array you want to produce needs to have the same number of elements as the original array. If you start with an array with 12 elements, you’ll need to make sure that your new array also has a total of 12 elements.

a is the array to be reshaped.

newshape is the new shape you want. You can specify an integer or a tuple of integers. If you specify an integer, the result will be an array of that length. The shape should be compatible with the original shape.

order: C means to read/write the elements using C-like index order,F means to read/write the elements using Fortran-like index order, A means to read/write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise. (This is an optional parameter and doesn’t need to be specified.)

<aside> 💡 Read more about internal organization of NumPy arrays here.

</aside>

How to convert a 1D array into a 2D array (how to add a new axis to an array)

  1. np.newaxis

  2. np.expand_dims

Using np.newaxis will increase the dimensions of your array by one dimension when used once. This means that a 1D array will become a 2D array, a 2D array will become a 3D array, and so on.

Indexing and Slicing

data = np.array([1, 2, 3])

data[1]
2

data[0:2]
array([1, 2])

data[1:]
array([2, 3])

data[-2:]
array([2, 3])

Screenshot 2023-06-17 213228.png

How to create an array from existing data?

  1. slicing

  2. indexing

  3. np.vstack()

  4. np.hsplit()

  5. .view()

  6. copy()

<aside> 💡 I have left it for later reading

</aside>

Basic array operations

  1. addition

  2. subtraction

  3. multiplication

  4. division

  5. .sum( )

  6. b.sum(axis=0

Broadcasting

NumPy understands that the multiplication should happen with each cell. That concept is called broadcasting. Broadcasting is a mechanism that allows NumPy to perform operations on arrays of different shapes. The dimensions of your array must be compatible, for example, when the dimensions of both arrays are equal or when one of them is 1. If the dimensions are not compatible, you will get a ValueError.

More array operations

  1. max( )

  2. min( )

  3. sum( )

  4. mean( )

  5. product == prod( )

  6. standard deviation = = std( )

Creating matrices

Be aware that when NumPy prints N-dimensional arrays, the last axis is looped over the fastest while the first axis is the slowest. For instance:

Screenshot 2023-06-17 215551.png

Screenshot 2023-06-17 215612.png

Screenshot 2023-06-17 215659.png

Screenshot 2023-06-17 215817.png

Generating random numbers

<aside> 💡 Something wrong

</aside>

How to get unique items and counts?

unique_values = np.unique(a)
print(unique_values)
[11 12 13 14 15 16 17 18 19 20]
unique_values, indices_list = np.unique(a, return_index=True)
print(indices_list)
[ 0  2  3  4  5  6  7 12 13 14]
unique_values, occurrence_count = np.unique(a, return_counts=True)
print(occurrence_count)
[3 2 2 2 1 1 1 1 1 1]

Transposing and reshaping a matrix

  1. arr.reshape( )

  2. arr.transpose( )

  3. arr.T

    Screenshot 2023-06-17 220937.png

Screenshot 2023-06-17 221024.png

How to reverse an array?

  1. np.flip( )

You can also reverse the contents of only one column or row. For example, you can reverse the contents of the row at index position 1 (the second row):

arr_2d[1] = np.flip(arr_2d[1])
print(arr_2d)
[[ 1  2  3  4]
 [ 8  7  6  5]
 [ 9 10 11 12]]

You can also reverse the column at index position 1 (the second column):

arr_2d[:,1] = np.flip(arr_2d[:,1])
print(arr_2d)
[[ 1 10  3  4]
 [ 8  7  6  5]
 [ 9  2 11 12]]

Reshaping and flattening multidimensional arrays

There are two popular ways to flatten an array :

  1. flatten( )

  2. ravel( )

The primary difference between the two is that the new array created using ravel() is actually a reference to the parent array (i.e., a “view”). This means that any changes to the new array will affect the parent array as well. Since ravel does not create a copy, it’s memory efficient.

How to access the docstring for more information

  1. help( )

  2. ?

  3. ??

When it comes to the data science ecosystem, Python and NumPy are built with the user in mind. One of the best examples of this is the built-in access to documentation. Every object contains the reference to a string, which is known as the docstring.

Working with mathematical formulas?

The ease of implementing mathematical formulas that work on arrays is one of the things that make NumPy so widely used in the scientific Python community.

Screenshot 2023-06-17 223301.png

What makes this work so well is that predictions and labels can contain one or a thousand values. They only need to be the same size.

We can visualize like this:

Screenshot 2023-06-17 223340.png

How to save and load NumPy objects?

  1. np.save

  2. np.savez

  3. np.savetxt

  4. np.load

  5. np.loadtxt

You will, at some point, want to save your arrays to disk and load them back without having to re-run the code. Fortunately, there are several ways to save and load objects with NumPy. The ndarray objects can be saved to and loaded from the disk files with loadtxt and savetxt functions that handle normal text files, load and save functions that handle NumPy binary files with a .npy file extension, and a savez function that handles NumPy files with a .npz file extension.

If you want to store a single ndarray object, store it as a .npy file using np.save. If you want to store more than one ndarray object in a single file, save it as a .npz file using np.savez. You can also save several arrays into a single file in compressed npz format with [savez_compressed](<https://numpy.org/doc/stable/reference/generated/numpy.savez_compressed.html#numpy.savez_compressed>).

Importing and exporting a CSV

It’s simple to read in a CSV that contains existing information. The best and easiest way to do this is to use Pandas.

import pandas as pd

<aside> 💡 a = np.array([2, 1, 5, 7, 4, 6, 8, 14, 10, 9, 18, 20, 22])

</aside>

import matplotlib.pyplot as plt

# If you're using Jupyter Notebook, you may also want to run the following
# line of code to display your code in the notebook:

%matplotlib inline
plt.plot(a)
# If you are running from a command line, you may need to do this:
# >>> plt.show()

Introduction

There are 6 general mechanisms for creating arrays:

  1. Conversion from other Python structures (i.e. lists and tuples)

  2. Intrinsic NumPy array creation functions (e.g. arange, ones, zeros, etc.)

    1. np.arange( )

    2. np.linspace( )

    3. np.eye(3) #for 2d array creation functions

    4. np.diag( )

    5. np.vander([1,2,3,4], 2)

    6. np.vander((1, 2, 3, 4), 4)

    7. np.zeros( )

    8. np.ones( )

    9. Random generator:

    from numpy.random import default_rng
    default_rng(42).random((2,3))

j. np.indices((3,3))

  1. Replicating, joining, or mutating existing arrays

  2. Reading arrays from disk, either from standard or custom formats

  3. Creating arrays from raw bytes through the use of strings or buffers

  4. Use of special library functions (e.g., random)

Indexing on ndarrays

[ndarrays](<https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray>) can be indexed using the standard Python x[obj] syntax, where x is the array and obj the selection.

Slicing

Basic slicing extends Python’s basic concept of slicing to N dimensions. Basic slicing occurs when obj is a [slice](<https://docs.python.org/3/library/functions.html#slice>) object (constructed by start:stop:step notation inside of brackets), an integer, or a tuple of slice objects and integers. [Ellipsis](<https://docs.python.org/3/library/constants.html#Ellipsis>)andand) [newaxis](<https://numpy.org/doc/stable/reference/constants.html#numpy.newaxis>) objects can be interspersed with these as well.

All arrays generated by basic slicing are always views of the original array.

The basic slice syntax is i:j:k where i is the starting index, j is the stopping index, and k is the step ().

Negative i and j are interpreted as n + i and n + j where n is the number of elements in the corresponding dimension. Negative k makes stepping go towards smaller indices.