#!/usr/bin/env python
# coding: utf-8
# ---
#
#
#
Department of Data Science
# Course: Tools and Techniques for Data Science
#
# ---
# Instructor: Muhammad Arif Butt, Ph.D.
# Lecture 3.6 (NumPy-06)
#
# # _Manipulating Array Elements.ipynb_
#
#
# # Learning agenda of this notebook
#
# 1. Updating existing values of NumPy array elements
# 2. Append new elements to a NumPy array using np.append()
# 3. Insert new elements in a NumPy array using np.insert()
# 4. Delete elements of a NumPy array using np.delete()
# 5. Alias vs Shallow Copy vs Deep Copy
# In[ ]:
# In[ ]:
# To install this library in Jupyter notebook
#import sys
#!{sys.executable} -m pip install numpy
# In[1]:
import numpy as np
np.__version__ , np.__path__
# In[ ]:
# ## 1. Updating Existing Values of Numpy Array Elements
# ### a. 1-D Arrays
# In[2]:
arr = np.random.randint(low = 1, high = 100, size = 10)
print("Original Array \n", arr)
arr[2] = 333
arr[-1] = 777
print("Updated Array \n", arr)
# ### b. 2-D Arrays
# In[3]:
# Creating 2-D array of size 4x4 of int type b/w interval 1 to 9
arr = np.random.randint(low = 1, high = 10, size = (4, 4))
print("Original Array \n", arr)
arr[0][1] = 77
arr[1][2] = 66
arr[2][-1] = 22
print("Updated Array \n", arr)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# ## 2. Append New Elements to Numpy Arrays
# - The `np.append()` method allows us to insert new values at the end of a NumPy array.
# - The method always returns a copy of the existing numpy array with the values appended to the given axis.
# ```
# np.append(arr, values, axis=None)
# ```
# - Where,
# - `arr` is the array in which we want to append
# - `values` must be of the correct shape (the same shape as `arr` excluding `axis`)
# - If `axis` is not specified, both `arr` and `values` are flattened before use.
# - If `axis` is specified, then `values` must be of the correct shape (the same shape as `arr` excluding `axis`)
# - The original array remains as such, as it does not occur in-place.
# ### a. Appending Elements in 1-D Arrays
# In[4]:
arr1 = np.random.randint(low = 1, high = 100, size = 10)
print("arr1 = ", arr1)
# In[5]:
# You can add a scalar value or a list of values at the end of a 1-D array
arr2 = np.append(arr1, [101, 202,303])
print("After append:")
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
print(id(arr1))
print(id(arr2))
# In[ ]:
# In[ ]:
# In[ ]:
# ### b. Appending Elements in 2-D Arrays
# **Example:** In case of 2-D Arrays if `axis` is not mentioned both `arr` and `values` are flattened before use
# In[6]:
arr1 = np.random.randint(low = 1, high = 10, size = (3,3))
print("arr1 = \n", arr1)
# In[7]:
# If the axis is not mentioned, values can be of any shape and both `arr` and `values` are flattened before use.
arr2 = np.append(arr1, [101, 202,303, 404, 505])
print("After append:")
print("arr1 = \n", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** Appending a Row to a 2-D array (`axis=0`)
# In[8]:
arr1 = np.random.randint(low = 1, high = 10, size = (4,3))
print("arr1 = \n", arr1)
print("shape: ", arr1.shape)
# In[9]:
# For appending at axis 0, the values argument must the same shape as `arr` excluding `axis`
# so the values should be a row vector, and in this case of shape (1,3), having 1 row and 3 columns
arr2 = np.append(arr1, [[101, 202,303]], axis=0)
print("After append:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** Appending a Column to a 2-D array (`axis=1`)
# In[10]:
arr1 = np.random.randint(low = 1, high = 10, size = (4,3))
print("arr1 = \n", arr1)
print("shape: ", arr1.shape)
# In[11]:
# For appending at axis 1, the values argument must the same shape as `arr` excluding `axis`
# so the values should be a column vector of shape (4,1), having 4 rows and 1 column
arr2 = np.append(arr1, [[101], [202], [303], [404]], axis=1)
print("After append:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# ## 3. Inserting New Elements in Numpy Arrays
# - The `np.insert()` method allows us to insert new values along the given axis before the given index.
# - The method always returns a copy of the existing numpy array with the values inserted to the given axis.
# ```
# np.insert(arr, index, values, axis=None)
# ```
# - Where,
# - `arr` is the array in which we want to insert
# - `index` is the index before which we want to insert
# - `values` [array_like] values to be added in the `arr`
# - If `axis` is not specified, both `arr` and `values` are flattened before use.
# - If `axis` is zero, a row is inserted (For 2-D arrays)
# - If `axis` is one, a column is inserted (For 2-D arrays)
# - The original array remains as such, as it does not occur in-place.
# ### a. Inserting Elements in 1-D Arrays
# In[12]:
arr1 = np.random.randint(low = 1, high = 100, size = 5)
print("arr1 = ", arr1)
# In[13]:
# You can insert a scalar value or a list of values in between array elements before the mentioned index
arr2 = np.insert(arr1, 3, [55, 66,77])
print("After insert:")
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# ### b. Inserting Elements in 2-D Arrays
# **Example:** In case of 2-D array, if `axis` is not mentioned the array is flattened first
# In[14]:
arr1 = np.random.randint(low = 1, high = 10, size = (3,4))
print("arr1 = \n", arr1)
# In[15]:
# Inserting a single value
arr2 = np.insert(arr1, 4, 55)
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = ", arr2)
# In[ ]:
# Inserting a multiple values
arr2 = np.insert(arr1, 4, [55, 66])
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** If axis=0, value(s) are added as a row before mentioned index
# In[16]:
arr1 = np.random.randint(low = 1, high = 10, size = (3,4))
print("arr1 = \n", arr1)
# In[17]:
# For axis = 0, note how the scalar value is replicated before insertion
arr2 = np.insert(arr1, 2, 55, axis=0)
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# For axis=0, note the size of values has to be 4 in this case (equal to number of columns)
arr2 = np.insert(arr1, 2, [55, 66, 77, 88], axis=0)
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** If axis=1, value(s) are added as a column at mentioned index
# In[ ]:
arr1 = np.random.randint(low = 1, high = 10, size = (3,4))
print("arr1 = \n", arr1)
# In[ ]:
# For axis = 1, note how the scalar value is replicated before insertion
arr2 = np.insert(arr1, 2, 55, axis=1)
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# For axis=1, note the size of values has to be 3 in this case (equal to number of rows)
arr2 = np.insert(arr1, 2, [55, 66, 77], axis=1)
print("After insert:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# ## 4. Deleting Elements of Numpy Arrays
# - The `np.delete()` method allows us to delete value(s) from an array at the given index
# - This function always returns a copy of the existing numpy array with the values deleted from the given axis.
# - If axis is not specified, values can be of any shape and will be flattened before use
# ```
# np.delete(arr, index, axis=None)
# ```
# - The original array remains as such, as it does not occur in-place.
# ### a. Deleting Elements from a 1-D Arrays
# **Example:**
# In[ ]:
arr1 = np.random.randint(low = 1, high = 10, size = 5)
print("arr1 = ", arr1)
# In[ ]:
# You can delete a scalar value from a specific index
arr2 = np.delete(arr1, 3)
print("After delete:")
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# **Example:**
# In[ ]:
arr1 = np.random.randint(low = 1, high = 100, size = 10)
print("arr1 = ", arr1)
# In[ ]:
# You can delete a list of values in between array elements from specific indices
arr2 = np.delete(arr1, [2,5])
print("After delete:")
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# ### b. Deleting Elements from a 2-D Arrays
# **Example:** Delete a specific element from a 2-D array, don't mention the axis. The resulting array is flattened before use
# In[ ]:
arr1 = np.random.randint(low = 1, high = 10, size = (3,3))
print("arr1 = \n", arr1)
# In[ ]:
arr2 = np.delete(arr1, 5)
print("After delete:")
print("arr1 = \n", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** Delete a specific row from an existing 2-D array
# In[ ]:
arr1 = np.random.randint(low = 1, high = 10, size = (4,4))
print("arr1 = \n", arr1)
# In[ ]:
arr2 = np.delete(arr1, 2, axis=0)
print("After delete:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# In[ ]:
# **Example:** Delete a specific column from an existing 2-D array
# In[ ]:
arr1 = np.random.randint(low = 1, high = 10, size = (4,4))
print("arr1 = \n", arr1)
# In[ ]:
arr2 = np.delete(arr1, 2, axis=1)
print("After delete:")
print("arr1 = \n", arr1)
print("arr2 = \n", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# ## 5. Assigning vs Coping NumPy Arrays
# ### a. Assigning two NumPy Arrays (Create an alias)
# In[18]:
arr1 = np.random.randint(low = 1, high = 10, size = 10)
# Creating a copy using assignment operator, both variables point at the same array
arr2 = arr1
print("arr1 = ", arr1)
print("arr2 = ", arr2)
print(id(arr1))
print(id(arr2))
# In[ ]:
# Change value in arr1 will also occur in arr2
arr2[2] = 55
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# ### b. View/Shallow Copy
# Arrays that share some data. The view method creates an object looking at the same data. Slicing an array returns a view of that array.
# In[19]:
import numpy as np
arr1 = np.random.randint(low = 1, high = 10, size = 10)
# Creating a shallow copy (view) using slice operator
arr2 = arr1[:]
print("arr1 = ", arr1)
print("arr2 = ", arr2)
print(id(arr1))
print(id(arr2))
# In[20]:
# Change value in arr1 will occur in arr2
arr2[2] = 55
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]:
# In[ ]:
# ### c. Deep Copy
# In[21]:
arr1 = np.random.randint(low = 1, high = 10, size = 10)
# Create a Deep copy using copy() method, which will create a new copy of the array
arr2 = arr1.copy()
print("arr1 = ", arr1)
print("arr2 = ", arr2)
print(id(arr1))
print(id(arr2))
# In[22]:
# Change value in array 1 will NOT occur in array 2
arr2[2] = 55
print("arr1 = ", arr1)
print("arr2 = ", arr2)
# In[ ]:
# In[ ]: