# numpy – INDEXING AND SELECTION, OPERATIONS

1. Grabbing one or more elements
3. Grabbing of 2D array elements
4. Conditional Selection of array elements
5. 1D Array (+-*/) 1D Array,
6. 2D Array -> Overall sum, rowwise sum, columnwise sum
7. Aabhar : Jose Portilla (Head of Data Science at Pierian Training) @Udemy
``````import numpy as np

# SELECTION OF ARRAY ELEMENTS
arr = np.arange(1,11)
print(arr)
# RES -> [ 1  2  3  4  5  6  7  8  9 10]
print(arr)
# RES ->6
print(arr[5:9])  #5th to 9th indexed value
# RES -> [6 7 8 9]
print(arr[5:]) # 5th till end
# RES -> [ 6  7  8  9 10]
print(arr[:5]) # From start till 5th
# RES -> [1 2 3 4 5]

arr[0:3] = 999    # All 3 elements will be now 999 - means values are broadcasted to all the elements which is not same as in list
print(arr)
# RES -> [999 999 999   4   5   6   7   8   9  10]

slicedArr = arr[0:5]
print(slicedArr)
# RES -> [999 999 999   4   5]
slicedArr[:]= np.arange(300,305)
print(slicedArr)
print(arr)
# RES -> [300 301 302 303 304]
#        [300 301 302 303 304   6   7   8   9  10]

sliceArr2 = arr.copy()
sliceArr2[:] = 111
print(sliceArr2)
print(arr)
# RES -> [111 111 111 111 111 111 111 111 111 111]
#        [300 301 302 303 304   6   7   8   9  10]

# -----  2D array selection and indexing
arr2d = np.array([ [5,10,15], [20,25,30], [35,40,45]])
print(arr2d)
# RES -> [[ 5 10 15]
#         [20 25 30]
#         [35 40 45]]
print(arr2d) # 1 row
# RES -> [ 5 10 15]
print(arr2d[0,2]) # 1st row last element - 15
# RES -> 15
print(arr2d[:2])  #Rows upto 2 excluding 2 means leave the 3rd row
# RES -> [[ 5 10 15]
#         [20 25 30]]
print(arr2d[:2, 1]) # Now form the extracted, 1st colum from all rows
# RES -> [10 25]
print(arr2d[:2, 1:]) # Now form the extracted, 1st and all the rest colum from all rows
# RES -> [[10 15]
#        [25 30]]

# CONDITIONAL SELECTION
x = np.arange(1,11)
boolX = x>8
print(boolX)
# RES -> [False False False False False False False False  True  True]
print(x[boolX])   # returns only those values > 8
# RES -> [ 9 10]
print(x[x<5]) # Shortcut way of writing
# RES -> [1 2 3 4]

# OPERATIONS
m = np.array([3,3,4])
print("m is : ", m)
# RES -> m is :  [3 3 4]
print(sum(m), max(m), min(m) , " ---", m.sum(), m.max(), m.min(), m.var(), m.std())
# RES -> 10 4 3  --- 10 4 3 0.22222222222222224 0.4714045207910317
print(m+5, m-m, m/2)
# RES -> [8 8 9] [0 0 0] [1.5 1.5 2. ]
print(np.sqrt(m), np.sin(m), np.log(m))
# RES -> [1.73205081 1.73205081 2.]
#        [ 0.14112001  0.14112001 -0.7568025 ]
#        [1.09861229 1.09861229 1.38629436]

# OPERATIONS on 2D array
m2d = np.arange(6).reshape(3,2)
print(m2d)
# RES -> [[0 1]
#         [2 3]
#         [4 5]]
print("Overall Sum : ", m2d.sum())
# RES -> 15
print("Column-wise Sum : ", m2d.sum(axis=0)) # 0 indicates rows -> Across the rows i.e downward
# RES -> [6 9]
print("Row-wise Sum : ", m2d.sum(axis=1)) # Across the columbs - horizontally
# RES -> [1 5 9]``````

# Python numpy – 01 – A quick reference

1. “numpy” is the fundamental package for scientific computing in Python.
2. Python library for creating N-Dimensional array
3. Great support for Liner-Algebra, Statistics Distribution, Trignometery
4. Aabhar : Jose Portilla (Head of Data Science at Pierian Training) @Udemy
5. Creating an array in 3 ways, accessing via index, some major methods
6. Broadcasting and how to prevent
7. 1D np.array([1,2]) 2D np.array([ [1,2], [3,4] ]) 3D np.array([ [ [1,2], [3,4] ] ])
``````import numpy as np
# ####  Create numpy array using
# A) Transforming standard python list
myList = [1,2,3]
myArray = np.array(myList)
print(type(myArray), "---", myArray)
# RES -> <class 'numpy.ndarray'> --- [1 2 3]

# B) Using Built-in functions
print(np.arange(0,11,2))   # o to 10 in steps of 2
# RES -> [ 0  2  4  6  8 10]
print(np.linspace(0,10,3)) # Evenly distributed 3 number bwn 0 to 10
# RES -> [ 0.  5. 10.]
print(np.zeros((1,5))) # 1D array with 5 zeroes, nD possible
# RES -> [[0. 0. 0. 0. 0.]]
print(np.ones(5)) #1D array with 5 ones, only 1D possible
# RES -> [1. 1. 1. 1. 1.]
print(np.eye(3))  #3x3 matrix with diagonal elements as 1
# RES -> [[1. 0. 0.]
#         [0. 1. 0.]
#         [0. 0. 1.]]

# C) By Generating random data
print(np.random.rand(2,3)) # 2x3 matrix with every number bwn o to 1
# RES -> [[0.08564555 0.5295177  0.82151728]
#         [0.83742842 0.96277555 0.84243966]]

print(np.random.randint(5,10,3)) # 3 integer no. bwn 5 to 10
# RES -> [6 6 8]
print(np.random.randint(5,55, (2,5)))  # any 12 integers between 5 to 55 in 2x5 format
# RES -> [[35 46 49 16 14]
#         [53 43 16 51 23]]

#randn : "standard normal" distribution with mean = 0 and SD = 1
print(np.random.randn(1,5))
# RES -> [[ 0.95835337 -1.70240379 -0.9072812  -0.51675364  1.25098128]]

#############  FEW MAJOR METHODS #############
x = np.arange(5,11)
print(x)
# RES -> [ 5  6  7  8  9 10]
print(x.max(), x.min(), x.argmax(), x.argmin() )  #max and min with their position value
# RES -> 10 5 5 0

#1 D array with 6 elements to it
print("X shape : " , x.shape)   # shape is property where as max() is method
# RES -> X shape :  (6,)
#2 D array, with 3 elements for each 1D array
y = x.reshape(2,3)
print(y)
# RES -> [[ 5  6  7]
#         [ 8  9 10]]

print("Y Shape : ", y.shape)
# RES -> Y Shape :  (2, 3)

#############  INDEXING & SLICING #############
arr = np.arange(1,11)
print(arr)
# RES -> [ 1  2  3  4  5  6  7  8  9 10]
print(arr)
#  RES -> 6
print(arr[5:9])  #5th to 9th indexed value
# RES -> [6 7 8 9]
print(arr[5:]) # 5th till end
# RES -> [ 6  7  8  9 10]
print(arr[:5]) # From start till 5th
# RES -> [1 2 3 4 5]

myArr = np.arange(11,66,11)
print(myArr)
# RES -> [11 22 33 44 55]
myArr[0:3] = 99 # Value is broadcasted to 1st 3 elements
print(myArr)
# RES -> [99 99 99 44 55]

myArr2 = myArr  # This myArr2 is basically a pointer
myArr2 = 0   # Modifying via pointer and hence original array will change
print(myArr)
# RES -> [ 0 99 99 44 55]

# To prevent, use copy() method
myArr3 = myArr.copy()
myArr3 = -1
print(myArr)
# RES -> [ 0 99 99 44 55]

x = np.arange(1,7)
print(x)
#RES -> [1 2 3 4 5 6]
boolX = x>3
print(boolX)
# RES -> [False False False  True  True  True]
print(x[boolX])   # returns only those values > 3
# RES -> [4 5 6]

###########  2D array selection and indexing ###########
# Array of 1D arrays
arr2d = np.array([ [5,10,15], [20,25,30], [35,40,45]])
print(arr2d)
# RES -> [[ 5 10 15]
#         [20 25 30]
#         [35 40 45]]
print(arr2d) # 1 row
# RES -> [ 5 10 15]
print(arr2d[0,2]) # 1st row last element - 15
# RES -> 15
print(arr2d[:2])  #Rows upto 2 excluding 2 means leave the 3rd row
# RES -> [[ 5 10 15]
#         [20 25 30]]
print(arr2d[:2, 1]) # Now form the extracted, 1st colum from all rows
# RES -> [10 25]
print(arr2d[:2, 1:]) # Now form the extracted, 1st and all the rest colum from all rows
# RES -> [[10 15]
#         [25 30]]``````

# Python Tuple – A quick reference

1. Like list only as sequence of values based on integer index, except they are – Immutable.
2. List -> [ ], Dict -> { }, Tuple -> (, )
3. Aabhar : http://do1.dr-chuck.com/pythonlearn/EN_us/pythonlearn.pdf
``````# Creating tuple using (, ) or tuple()
myTuple = tuple() # With no argument, creates an empty tuple
#  Pass only Iteratable items only like string, list of tuple - no int/float
#myTuple2 = tuple(100)
myTuple = tuple('IND') #Will create a tuple with all chars individually
print(type(myTuple), " ----", myTuple)
# RES -> <class 'tuple'>  ---- ('I', 'N', 'D')

myTuple2 = (100, ) # (100)- Without comma, it will be just plain int class
myTuple2 = (100, 200.0, (True,))
print(type(myTuple2), " ----", myTuple2)
# RES -> <class 'tuple'>  ---- (100, 200.0, (True,))

# Traversing of elements
for myTups in myTuple2: print(myTups)
""" RES ->
100
200.0
(True,)
"""

for x in tuple('OM'): print(x)
""" RES ->
O
M
"""

for i in range(len(myTuple)): print(myTuple[i])
""" RES ->
I
N
D
"""

# Slice
print(myTuple2[1:])
# RES -> (200.0, (True,))

#TypeError: 'tuple' object does not support item assignment
#myTuple2 = 'Cant assing as immutable'

#The tuple assignment
person = ('Bachchan', 70)
name = person
age = person
print(name, "--", age)
# RES -> Bachchan -- 70

# Treat tuple more like a key-value pair for a symmetric tuples
myTup = ( ('XX', 'Male', 30), ('YY', 'Female', 55), ('ZZ', 'Female', 18) )
for name,gender,age in myTup: print(name, gender, age)
""" RES ->
XX Male 30
YY Female 55
ZZ Female 18
"""

# Comparing two lists - item by item until you get the very first match
print ( (1,2,3) > (1,1,3) )
# RES -> True

name, domain = myEmail.split('@') # Split is of type list
print(name, domain)

# Python Dictionary – A quick reference

1. Built-in data structure, Mutable
2. Unordered collection of items in the form of a key: value pair
3. Aabhar : https://allinpython.com/explain-python-dictionary-in-detail/
``````# Create dictionary using {} or dict
myEmptyOrInitializableDict = {}
print(type(myEmptyOrInitializableDict) , " --- ", myEmptyOrInitializableDict)
# RESULT -> <class 'dict'>  ---  {}

myInitializedDict = {'PythonDesignedBy' : 'Van Rossum' }
print(type(myInitializedDict), "---", myInitializedDict)
# RESULT -> <class 'dict'> --- {'PythonDesignedBy': 'Van Rossum'}

myDict = dict(language='Python', usage='Scientific', rating=5)
#myDict2 = dict('language'='PHP', 'usage'='Web Development') # SyntaxError as keys are made of quoted
print(myDict)
# RESULT -> {'language': 'Python', 'usage': 'Scientific', 'rating': 5}

print(type(myDict.keys()), " ----", myDict.keys())
print(type(myDict.values()), " ----" , myDict.values())
print('language' in myDict) # Check if key is present
print('PHP' in myDict.values()) # Check if value is present
# RESULT -> <class 'dict_keys'>  ---- dict_keys(['language', 'usage', 'rating'])
# RESULT -> <class 'dict_values'>  ---- dict_values(['Python', 'Scientific', 5])
# RESULT -> True
# RESULT -> False

#Traversing a dictionary
for key in myDict:
print(key , "->" , myDict['language'])

""" RESULT ->
language -> Python
usage -> Python
rating -> Python
"""

#Major Methods
print( myDict.get('rating') )
print(myDict.pop('rating') , " -- After Pop myDict is -- ", myDict)
print(myDict.popitem(), " -- After popitem myDict is --", myDict) # removes the last most item
#RESULT -> 5
#RESULT -> 5  -- After Pop myDict is --  {'language': 'Python', 'usage': 'Scientific'}
#RESULT -> ('usage', 'Scientific')  -- After popitem myDict is -- {'language': 'Python'}

myDict.update({'popularity' : 'High'})
myDict.update(dict(usage = 'Univeral'))
print(myDict)
#RESULT -> {'language': 'Python', 'popularity': 'High', 'usage': 'Univeral'}

myDictCopy = myDict.copy();
print(myDictCopy);
#RESULT -> {'language': 'Python', 'popularity': 'High', 'usage': 'Univeral'}

myDictCopy.clear()
print(myDictCopy)
#RESULT -> {}``````