Python NumPy
NumPy — Numerical Python, for working with arrays. Python’s built-in lists serve the same purpose but are slow. NumPy arrays are up to 50× faster — they’re stored at one continuous place in memory (locality of reference), so processes can access and manipulate them efficiently.
Part 1 — Creating arrays & data types
Creating an array
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
arr = np.arrange(2, 10, 2)
>> [2, 4, 6, 8]
arr = np.arrange(10)
>> [1, 2, 3, 4, 5, 6, 7, 8, 9]
# array in NumPy is called ndarray
arr = np.linspace(-2, 5, 50) # 50 data points including -2 and 5
# Generates a numpy array of numbers EVENLY SPACED over a specified intervalDimensions
# 0-D Arrays / Scalars are elements in an array
arr = np.array(42)
# 1-D Arrays: made up of 0-D array elements. Uni-dimensional
arr = np.array([1, 2, 3, 4, 5])
# 2-D Arrays: made up of 1-D array elements. Matrix / 2nd-order tensor
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 3-D Arrays: made up of 2-D array elements. 3rd-order tensor
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr.ndm # Check number of dimensions
np.array([1, 2, 3], ndim=5) # Define number of dimensions
# in this example, [1, 2, 3] is the innermost dimension with 3 elements.Array indexing
# It always goes from macro to micro.
# Access 1-D Arrays
arr = np.array([1, 2, 3, 4])
print(arr[0])
>> 1
print(arr[1] + arr[2])
>> 5
# Access 2-D Arrays: Table with rows and columns
# [x, y]: x array/row, y element/column
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr[0, 1])
>> 2
# Access 3-D Arrays
# [x, y, z]: x array, y array, z element
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr[0, 1, 2])
>> 6
# Negative indexing
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr[1, -1])
>> 6Array slicing
# [start:end:step]
# start is inclusive, end is exclusive
# you can use x:y to select elements or arrays
# 1D array
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[1:5])
>> [2, 3, 4, 5]
print(arr[1:5:2])
>> [2, 4]
print(arr[2:])
>> [3, 4, 5, 6, 7]
# vice versa for :4 but not included
print(arr[-3:-1])
>> [5, 6]
# 2D Arrays
print(arr[1, 1:4]) # Second array, elements index 1-4
print(arr[0:2, 2]) # Take the array index 0 and 1. Element index 2 in both.
print(arr[0:2, 0:2]) # Take the array index 0 and 1. Element index 0 and 1 in both.Data types
# Data types
i # integer
b # boolean
u # unsigned integer
f # float
c # complex float
m # timedelta
M # datetime
O # object
S # string
U # unicode string
V # fixed chunk of memory for other type
# Checking data type
arr.dtype
# Create array with data type
arr = np.array([1, 2, 3], dtype='S') # string
arr = np.array([1, 2, 3], dtype='i4') # 4 bytes integer
# Convert data type on existing array
arr = np.array([1, 2, 3])
new_arr = arr.astype('i')Part 2 — Copy vs View, Shape, Reshape, Iterate
Copy vs View
Copy is a new array. View is a view of the original array.
arr = np.array([1, 2, 3])
# COPY: Owns its data
# Whatever changes are made to original/copy does not affect copy/original
copy_arr = arr.copy()
# VIEW: Does not own its data
# Whatever changes are made to original/view affects view/original
view_arr = arr.view()
# Check if Array owns its data
# Every NP array has the attribute base that returns None if array owns data.
print(copy_arr.base)
print(view_arr.base)
>> None
>> [1, 2, 3]Array shapes
# Shape of 2D array
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape)
>> (2, 3)
# 2 dimensions, each with 3 elements
# For higher dimensions
arr = np.array([1, 2, 3], ndmin=5)
print(arr)
print(arr.shape)
>> [[[[[1, 2, 3]]]]]
>> (1, 1, 1, 1, 3)Array reshaping
arr.reshape(x, y, ...)
# number of arrays, number of elements (or arrays) in each array
# make sure you count the grouping properly
# reshaped array is a view
# EG: Reshaping a 1-D array into 2-D array
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
new_arr = arr.reshape(2, 5)
print(new_arr)
>> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
# Unknown dimensions (Convert 1-D into 3-D)
# You skipping a dimension?
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
new_arr = arr.reshape(2, 2, -1)
print(new_arr)
>> [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
# Flattening arrays
arr = np.array([[1, 2, 3], [4, 5, 6]])
new_arr = arr.reshape(-1)
print(new_arr)
>> [1, 2, 3, 4, 5, 6]Array iterating
# 1-D iterating
arr = np.array([1, 2, 3])
for x in arr:
print(x)
# 2-D iterating
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
print(x)
>> [1, 2, 3]
>> [4, 5, 6]
# 2-D iterating (to get the elements)
for x in arr:
for y in x:
print(y)nditer()
arr = np.array(the craziest dimensions)
# Gets the basic elements
for x in np.nditer(arr):
print(x)
# Gets the basic elements, change datatype of elements while iterating
for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):
print(x)
# Gets the basic elements, skipping elements
for x in np.nditer(arr[x:y...]):
print(x)ndenumerate()
# 1-D Array
arr = np.array([1, 2, 3])
for idx, x in np.ndenumerate(arr):
print(idx, x)
>> (0,) 1
>> (1,) 2
>> (2,) 3
# 2-D Array
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
for idx, x in np.ndenumerate(arr):
print(idx, x)
>> (0, 0) 1
>> (0, 1) 2
>> (0, 2) 3
>> (0, 3) 4
>> (1, 0) 5
>> (1, 1) 6
>> (1, 2) 7
>> (1, 3) 8Part 3 — Joining
Array joining using axes
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr3 = np.concatenate((arr1, arr2))
>> [1, 2, 3, 4, 5, 6]Part 4 — NumPy operations
print(a.shape) # Return the shape or number of elements in a 1D array
print(a - 5) # Subtract each element by 5
print(a**2) # Square each element
print(a*2) # Each element * 2
print(a/16) # Divide each element by 16
print(np.sqrt(a)) # Perform the square root of each element
print(np.sum(a)) # Sum all elements
print(np.min(a)) # Return the minimum
print(np.max(a)) # Return the maximum
print(np.sort(a)) # Sort from minimum to maximum
print(np.mean(a)) # Return the mean
print(np.median(a)) # Return the median
print(np.std(a)) # Return the standard deviationSee next
- Python-Matplotlib — visualise NumPy arrays
- Python-Statistics —
statisticsmodule (different from NumPy)