Unit 3 Numpy
Unit 3 Numpy
Usually, numpy is imported with np alias. alias is alternate name for referencing the same
thing.
import numpy as np
>>>np.__version__
'1.16.4'
NumPy is used to work with arrays. The array object in NumPy is called ndarray.
We can create a NumPy ndarray object by using the array() function.
To create an ndarray, we can pass a list, tuple or any array-like object into the array() method,
and it will be converted into an ndarray:
Example:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
output: [1 2 3 4 5]
type(): This built-in Python function tells us the type of the object passed to it. Like in above code it
shows that arr is numpy.ndarray type.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
output: [1 2 3 4 5]
<class 'numpy.ndarray'>
Dimensions in Arrays
A dimension in arrays is one level of array depth (nested arrays).
0-D Arrays
0-D arrays, or Scalars, are the elements in an array. Each value in an array is a 0-D array.
Example
import numpy as np
arr = np.array(42)
print(arr)
Output: 42
1-D Arrays
An array that has 0-D arrays as its elements is called uni-dimensional or 1-D array.
These are the most common and basic arrays.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
output: [1 2 3 4 5]
2-D Arrays
An array that has 1-D arrays as its elements is called a 2-D array.
These are often used to represent matrix or 2nd order tensors.
NumPy has a whole sub module dedicated towards matrix operations called numpy.mat
Example
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
output:
[[1 2 3]
[4 5 6]]
3-D arrays
An array that has 2-D arrays (matrices) as its elements is called 3-D array.
These are often used to represent a 3rd order tensor.
Example
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
print(arr)
Output:
[[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]]
Example
import numpy as np
a = np.array(42)
b = np.array([1, 2, 3, 4, 5])
c = np.array([[1, 2, 3], [4, 5, 6]])
d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
print(a.ndim)
print(b.ndim)
print(c.ndim)
print(d.ndim)
Output:
Example
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr[0])
print(arr[2] + arr[3])
Output:
Example
import numpy as np
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print(arr[0, 1])
Output:
To access elements from 3-D arrays we can use comma separated integers representing the
dimensions and the index of the element.
Example
Access the third element of the second array of the first array:
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr[0, 1, 2])
Output:
Example Explained
The first number represents the first dimension, which contains two arrays:
[[1, 2, 3], [4, 5, 6]]
and:
[[7, 8, 9], [10, 11, 12]]
Since we selected 0, we are left with the first array:
[[1, 2, 3], [4, 5, 6]]
The second number represents the second dimension, which also contains two arrays:
[1, 2, 3]
and:
[4, 5, 6]
Since we selected 1, we are left with the second array:
[4, 5, 6]
The third number represents the third dimension, which contains three values:
4
5
6
Since we selected 2, we end up with the third value:
6
Negative Indexing
Use negative indexing to access an array from the end.
Example
Print the last element from the 2nd dim:
import numpy as np
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print( arr[1, -1])
Output:
10
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[1:5])
Output:
[2 3 4 5]
Note: The result includes the start index, but excludes the end index.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[4:])
Output:
[5 6 7]
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[:4])
Output:
[1 2 3 4]
Negative Slicing
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[-3:-1])
Output:
[5 6]
STEP
Use the step value to determine the step of the slicing:
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[1:5:2])
Output:
[2 4]
From the second element, slice elements from index 1 to index 4 (not included):
import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[1, 1:4])
Output:
[7 8 9]
import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[0:2, 2])
Output:
[3 8]
Example
From both elements, slice index 1 to index 4 (not included), this will return a 2-D array:
import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[0:2, 1:4])
Output:
[[2 3 4]
[7 8 9]]
strings - used to represent text data, the text is given under quote marks. e.g. "ABCD"
integer - used to represent integer numbers. e.g. -1, -2, -3
float - used to represent real numbers. e.g. 1.2, 42.42
boolean - used to represent True or False.
complex - used to represent complex numbers. e.g. 1.0 + 2.0j, 1.5 + 2.5j
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 ( void )
Checking the Data Type of an Array
The NumPy array object has a property called dtype that returns the data type of the array:
Example
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr.dtype)
Output:
int32
Example
import numpy as np
arr = np.array([1, 2, 3, 4], dtype='i4')
print(arr)
print(arr.dtype)
Output:
[1 2 3 4]
int32
Example
A non integer string like 'a' cannot be converted to integer (will raise an error):
import numpy as np
arr = np.array(['a', '2', '3'], dtype='i')
print(arr)
Output:
The best way to change the data type of an existing array, is to make a copy of the array with
the astype() method.
The astype() function creates a copy of the array, and allows you to specify the data type as a
parameter.
The data type can be specified using a string, like 'f' for float, 'i' for integer etc. or you can use the
data type directly like float for float and int for integer.
Example
Change data type from float to integer by using 'i' as parameter value:
import numpy as np
arr = np.array([1.1, 2.1, 3.1])
newarr = arr.astype('i')
print(newarr)
print(newarr.dtype)
Output:
[1 2 3 4]
int32
Example
Change data type from float to integer by using int as parameter value:
import numpy as np
arr = np.array([1.1, 2.1, 3.1])
newarr = arr.astype(int)
print(newarr)
print(newarr.dtype)
Output:
[1 2 3 4]
int32
Example
import numpy as np
arr = np.array([1, 0, 3])
newarr = arr.astype(bool)
print(newarr)
print(newarr.dtype)
Output:
bool
NumPy Array Shape
Shape of an Array
NumPy arrays have an attribute called shape that returns a tuple with each index having the number of
corresponding elements.
Example
import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(arr.shape)
Output:
(2, 4)
The example above returns (2, 4), which means that the array has 2 dimensions, where the first
dimension has 2 elements and the second has 4.
Example
Create an array with 5 dimensions using ndmin using a vector with values 1,2,3,4 and verify that last
dimension has value 4:
import numpy as np
arr = np.array([1, 2, 3, 4], ndmin=5)
print(arr)
print('shape of array :', arr.shape)
Output:
[[[[[1 2 3 4]]]]]
Reshaping arrays
Reshaping means changing the shape of an array.
The shape of an array is the number of elements in each dimension.
By reshaping we can add or remove dimensions or change number of elements in each
dimension.
Convert the following 1-D array with 12 elements into a 2-D array. The outermost dimension will
have 4 arrays, each with 3 elements:
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(4, 3)
print(newarr)
Output:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)
Output:
[ 3 4]
[ 5 6]]
[[ 7 8]
[ 9 10]
[11 12]]]
Yes, as long as the elements required for reshaping are equal in both shapes.
We can reshape an 8 elements 1D array into 4 elements in 2 rows 2D array but we cannot
reshape it into a 3 elements 3 rows 2D array as that would require 3x3 = 9 elements.
Example
Try converting 1D array with 8 elements to a 2D array with 3 elements in each dimension (will raise
an error):
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(3, 3)
print(newarr)
Output:
newarr = arr.reshape(3, 3)
Unknown Dimension
You are allowed to have one "unknown" dimension.
Meaning that you do not have to specify an exact number for one of the dimensions in the
reshape method.
Pass -1 as the value, and NumPy will calculate this number for you.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(2, 2, -1)
print(newarr)
Output:
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
Example
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
newarr = arr.reshape(-1)
print(newarr)
Output:
[1 2 3 4 5 6]
Iterating Arrays
Iterating means going through elements one by one.
As we deal with multi-dimensional arrays in numpy, we can do this using basic for loop of
python.
If we iterate on a 1-D array it will go through each element one by one.
Example
import numpy as np
arr = np.array([1, 2, 3])
for x in arr:
print(x)
Output:
Example
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
print(x)
Output:
[1 2 3]
[4 5 6]
If we iterate on a n-D array it will go through n-1th dimension one by one. To return the actual values,
the scalars, we have to iterate the arrays in each dimension.
Example
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
for y in x:
print(y)
Output:
Example
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
for x in arr:
print(x)
Output:
[[1 2 3]
[4 5 6]]
[[ 7 8 9]
[10 11 12]]
Example
Iterate down to the scalars. To return the actual values, the scalars, we have to iterate the arrays in
each dimension.
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
for x in arr:
for y in x:
for z in y:
print(z)
Output:
4
5
10
11
12
NumPy does not change the data type of the element in-place (where the element is in array) so it
needs some other space to perform this action, that extra space is called buffer, and in order to enable
it in nditer() we pass flags=['buffered'].
Example
import numpy as np
arr = np.array([1, 2, 3])
for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):
print(x)
Output:
b'1'
b'2'
b'3'
Example
import numpy as np
arr = np.array([1, 2, 3])
for idx, x in np.ndenumerate(arr):
print(idx, x)
Output:
(0,) 1
(1,) 2
(2,) 3
import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
for idx, x in np.ndenumerate(arr):
print(idx, x)
Output:
(0, 0) 1
(0, 1) 2
(0, 2) 3
(0, 3) 4
(1, 0) 5
(1, 1) 6
(1, 2) 7
(1, 3) 8
Example
import numpy as np
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.concatenate((arr1, arr2))
print(arr)
Output:
[1 2 3 4 5 6]
Example
Output:
[[1 2 5 6]
[3 4 7 8]]
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 3)
print(newarr)
Output:
If the array has less elements than required, it will adjust from the end accordingly.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 4)
print(newarr)
Output:
Note: We also have the method split() available but it will not adjust the elements when elements are
less in source array for splitting like in example above, array_split() worked properly but split() would
fail.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 3)
print(newarr[0])
print(newarr[1])
print(newarr[2])
Output:
[1 2]
[3 4]
[5 6]
Example
import numpy as np
arr = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
newarr = np.array_split(arr, 3)
print(newarr)
Output:
Example
Split the 2-D array into three 2-D arrays along rows.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])
newarr = np.array_split(arr, 3, axis=1)
print(newarr)
Output:
[10],
[13],
[ 5],
[ 8],
[11],
[14],
[ 6],
[ 9],
[12],
[15],
[18]])]
>>>
Example
Use the hsplit() method to split the 2-D array into three 2-D arrays along rows.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])
newarr = np.hsplit(arr, 3)
print(newarr)
Output:
[array([[ 1],
[ 4],
[ 7],
[10],
[13],
[ 5],
[ 8],
[11],
[14],
[ 6],
[ 9],
[12],
[15],
[18]])]
Searching Arrays
You can search an array for a certain value, and return the indexes that get a match.
To search an array, use the where() method.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 4, 4])
x = np.where(arr == 4)
print(x)
Output:
The example above will return a tuple: (array([3, 5, 6],), Which means that the value 4 is
present at index 3, 5, and 6.
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
x = np.where(arr%2 == 0)
print(x)
Output:
Example
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
x = np.where(arr%2 == 1)
print(x)
Output:
Sorting Arrays
Sorting means putting elements in an ordered sequence.
Ordered sequence is any sequence that has an order corresponding to elements, like numeric
or alphabetical, ascending or descending.
The NumPy ndarray object has a function called sort(), that will sort a specified array.
Example
import numpy as np
arr = np.array([3, 2, 0, 1])
print(np.sort(arr))
Output:
[0 1 2 3]
Note: This method returns a copy of the array, leaving the original array unchanged. You can also sort
arrays of strings, or any other data type:
Example
import numpy as np
arr = np.array(['banana', 'cherry', 'apple'])
print(np.sort(arr))
Output:
Example
import numpy as np
arr = np.array([True, False, True])
print(np.sort(arr))
Output:
If you use the sort() method on a 2-D array, both arrays will be sorted:
Example
import numpy as np
arr = np.array([[3, 2, 4], [5, 0, 1]])
print(np.sort(arr))
Output:
[[2 3 4]
[0 1 5]]