# NumPy Notes ><i class="fa fa-file-text"></i> [NumPy Tutorial](https://www.w3schools.com/python/numpy/default.asp) :::success :bulb: **Axis demonstration** axis = 0 | Vertical effect | Joins rows (stack one array on top of the other) axis = 1 | Horizontal effect | Joins columns (place arrays side-by-side) ::: ```python! import numpy as np arr1 = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]]) #initializing 3d array arr2 = np.array([1,2,3,4,5,6,7,8]) print('3d array:\n', arr1) #print array print('dimensions:', arr1.ndim) #print dimensions print('@ index 0:\n', arr1[0]) #printing 2d array at index 0 print('@ index [0,1]:', arr1[0,1]) #printing array at [0,1] print('@ index [0,1,2]:', arr1[0,1,2]) # printing value at [0,1,2] print('Last element from 2nd dim: ', arr1[0,0,-1]) # negatives to access last value print('Slicing last array 1 to 2: ', arr1[1,1,1:3]) #slicing is exclusive print('Slicing first array 0 to 1: ', arr1[0,0,:2]) #slicing with end bounds vice versa print('Slicing index 3 from the end to index 1 from the end: ', arr2[-3:-1]) #slicing with negatives print('Slicing and stepping by 2: ', arr2[1:5:2]) #stepping arr3 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) print('Slicing index 1 to index 4', arr3[0:2, 1:4]) #for rows 0 to 2, cols 1 to 4 print('Every other value', arr2[::2]) #every other value with stepping print('Data type: ', arr1.dtype) # print the arr content type arr4 = np.array(['dog', 'pig', 'cat'], dtype ='U') #initializing arrays with specific type arr5 = arr2.astype('f') #copying another array and changing data type arr6 = arr4.copy() #copies another array; copies own data arr7 = arr4.view() #views another array; views don't own data and is tied to the OG print('OG:', arr4) arr4[0] = 'FAT' print('Changed OG:', arr4) print('copy:' , arr6) print('view:', arr7) #change view also changes the OG print(arr6.base) # checks for base array print(arr1.shape) #print shape arr8 = np.array([1,2,3,4], ndmin = 5) #makes an array with specific dimension print('5d array:', arr8) arr9 = arr2.reshape(2,4) #reshaping an array; reshapes are tied to the OG arr10 = arr2.reshape(2,2,-1) #use -1 for np to calculate reshaping for you arr11 = arr10.reshape(-1) #-1 flattens an array to 1D print('Printing each value in arr1: ') for x in arr1: #iterate through arrays with for loops for y in x: for z in y: print(z) print('Printing with nditer: ') for x in np.nditer(arr1): # alt iteration shortcut print(x) print('Printing changed data type: ') for x in np.nditer(arr1, flags = ['buffered'], op_dtypes=['S']): #change each element data type with nditer print (x) print('Printing index values: ') for idx, x in np.ndenumerate(arr1): #ndenumerate to get index values print (idx, x) arr12 = np.concatenate((arr4,arr6)) #concatenate arrays arr13 = np.stack((arr4,arr6), axis = 1) #stack is the same as concat but adds a new dimension arr14 = np.vstack((arr4,arr6)) #another way for axis=0 arr15 = np.hstack((arr4,arr6)) #another way for axis=1 arr16 = np.dstack((arr4,arr6)) #stacking for 3d arr17 = np.array_split(arr2,3) #splitting an array --- times print("Split array 3 sections:", arr17) #print split array print ('The first split array:', arr17[0]) #access split arrays arr18 = np.vsplit(arr14,2) #opposite for vstack; vice versa for hsplit and hstack a = np.where(arr2 == 2) #where() tells you where element matches b = np.searchsorted(arr2, 2, side = "left") #returns index value where the element should be inserted to maintain sort #use side = to specify which side to start search c = np.searchsorted(arr2, [2, 4, 6]) #you can also searchsort a set of numbers arr19 = np.array([3,2,1,6,8,88]) print("Sorted array:", np.sort(arr19)) #sorts and prints array; works with strings, booleans, 2d arrays... d = [True, True, False, True, False, False] #created a list of booleans print('Boolean driven array:', arr19[d]) #prints array according to the boolean list #this is called filter array ``` # NumPy Random ### NORMAL DATA DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893525-8ee8623f560e5e919a4fc785de7341b2.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T020353Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=46c9bfbeae56b92d2cc23e65db0dfdd4df427dd64b0f23a62dcb20166a825276) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893557-3f69635c4836dd9992c1e39d88877762.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T020718Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=d305ccd5c4196f42e33f6fa1a1ae59992db9abb90038315a908fb7227c29ec03) ### BINOMIAL DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893586-0a27dd10581c8fa510cdb537dd0bafea.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T020923Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=92628b38992929b28abc06f478a6c12920c0a521273acd55ec180c3694153291) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893594-7273a96b9590e5219a734c114ecf4df3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021002Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=a5063e141dffce1e1aa931dd8f410f04dffa43dffcf441078b32c6e5cb0b057d) >[!Tip] >Normal distribution is continuous while binomial is discrete ### POISSON DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893607-67f4964ea2a80f1d734b34f7fdbe79e0.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021137Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=e4bd997fef28d9ddf8beb36fb8e01d8bfaeae61d4a209abc8c17d4bdc934ec93) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893613-e3eaa9c7513c8e1164ad6193672977a3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021217Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=22bf14b2048d21f310bb9dbda00b16e9b47f6ad732dffe010df7ba4f5e497112) >[!Tip] > - Poisson is discrete and normal is continuous > - Poisson has infinite amount of outcomes while binomial only has 2 ### UNIFORM DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893639-dd70ea4f6bc46af616d0757954815f17.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021454Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=d0dcb6370bf311b4fd2d36035a4a32607c473636ed0b11ac7042e1c6fbdd1fd2) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893646-f37a71a2cf3b34dc29c58f6407b90534.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021557Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=4a3bc149f67f5831ccda9f74fa0bcf3339148bb7d0cdf305e85afe24cd99dabe) ### LOGISTIC DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893664-a7b5ba17d7e9249414e35f7c46e157ef.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021706Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=0d0ebcaf05ed0710519319e0d3fe7f7188b9180ec532a8c73ca56284912ac2a7) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893669-47ba37da42fa9dc331f043fd376eb275.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021748Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=94ed0ec0ebc9c3899bd219c789a15832ad5243af1c8892c08ee61fc9fd2ca73e) >[!Tip] >Compared to normal: logistic distribution has more area under the tails, meaning it represents more possibility of occurrence of an event further away from mean ### MULTINOMIAL DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893681-5196df4124d95405995b82eda8bb0007.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021840Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=dc723651cb429c506206d85f34a2f4d61f70173f506ff1d6f1ba826f6fdd8850) ### EXPONENTIAL DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893692-d309cef94cbe9fbba139335db84c0ca3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T021948Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=a20dc3e4dc48447e6a019ba59dd1ab33381b54eb088c845058fb1e43d4fcb928) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893697-b097bd24bf0963754b30ae65b3f93063.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022027Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=496c8c3c4340683f6779e9beeff6527510063da5e9a76152955f619582e1916e) >[!Tip] >Poisson deals w/ num of occurrences of an event in a time period; exponential deals w/ the time btw events ### CHI SQUARE DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893708-22d41b6f953d05d2b280c378ec97fbf3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022132Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=509c7466a0494f78a75175cb7edb201e1bab0eb0fbc398ca78fb48931ee8be06) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893715-bb7776a634567ec87262031e31e80283.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022209Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=a85197fe4cb4049d45a14102a58748d7c185bf05221ff67688e4f5fdacf0edf0) ### RAYLEIGH DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893726-5f5fc627b52cc6e98cece2df1c54c5fd.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022316Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=fb789166ecac02e28e979c7214cf7f7d583d7370c30c5a307510fc852ac1955f) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893730-925f7aab5e033aeff6255c1d440d6129.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022354Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=1af63a7526e007aa94a61ae91f5e50f8c7fe0892a9a617df43212214c752aea1) ### PARETO DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893737-81d3f5a5625d8c35dac6b28aab697fbc.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022453Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=72e9628c76bec3c0e30a4cf7c30d5d5e0470efe365eff9eec4ad52dab5f518e6) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893743-b91d2eceffe3269568b5c27f92c716b4.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022529Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=d0cbddf0c4eae42e0439e65b15f24869274bc1d5b1e891090c9db386cd2f1189) ### ZIPF DISTRIBUTION ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893757-4a4c8bf66822edfdb3477b55dad51432.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022701Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=5a03753bd87fe28b9a124dce18aa9ac4770ecf077e6d4f560a0634351d7fab2d) ![image](https://awesomescreenshot.s3.amazonaws.com/image/2249111/54893768-1266bdd654efb077516f54109a4888ac.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20250610%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250610T022742Z&X-Amz-Expires=28800&X-Amz-SignedHeaders=host&X-Amz-Signature=d34252de93196a80ac4c7c0796daa60389248ba55497f51d0ffd6480f1fc48c3) ```python! from numpy import random import matplotlib.pyplot as plt import seaborn as sns import numpy as np arr1 = np.array([1,2,3,4,5]) a = random.randint(100) #generates random int from 0 to 100 b = random.rand() #generates random float from 0 to 1 c = random.randint(100, size = (5)) #generates a 1D array with 5 random int d = random.randint(100,size = (5,2)) #random 2D array! e = random.choice([1,5,99,0]) #randomly picks an element from the array f = random.choice([0,99,84,3], size = (3,5)) #randomly generates 2D array using listed elements and specified size g = random.choice([3, 5, 7, 9], p=[0.1, 0.3, 0.6, 0.0], size=(100)) #you can control probabilities by assigning a num for each element 0-1 #0 means never occur; 1 means allways occur random.shuffle(arr1) #randomly shuffles array; changes the OG h = random.permutation(arr1) #shuffles array; does NOT change the OG sns.displot([0,1,0,1,2,3,4,5], kind = 'kde') #create displot plt.show() #shows displot; kde makes the graph a line, otherwise its a histogram i = random.normal(loc =1, scale =2, size =(2,3)) #RANDOM NORMAL DISTRIBUTION size 2x3 with mean at 1 and standard deviation of 2 j = random.binomial(n=10, p=0.5,size= 10) #RANDOM BINOMIAL DISTRIBUTION 10 trials for coin toss generate 10 data points k = random.poisson(lam=2, size=10)#RANDOM POISSON DISTRIBUTION random 1x10 distribution for occurrence 2 l = random.uniform(size=(2,3)) #RANDOM UNIFORM DISTRIBUTION 2x3 uniform distribution sample m = random.logistic(loc=1, scale=1, size=(2,3)) #RANDOM LOGISTIC DISTRIBUTION 2x3 samples from a logistic distribution with mean at 1 and stddev 2.0 n = random.multinomial(n=6, pvals=[1/6, 1/6, 1/6, 1/6, 1/6, 1/6]) #RANDOM MULTINOMIAL DISTRIBUTION dice roll exampple o =random.exponential(scale=2, size=(2, 3)) #RANDOM EXPONENTIAL DISTRIBUTION 2.0 scale with 2x3 size p = random.chisquare(df=2, size=(2, 3)) #RANDOM CHI SQUARE DISTRIBUTION degree of freedom 2 with size 2x3 q = random.rayleigh(scale=2, size=(2, 3)) #RANDOM RAYLEIGH DISTRIBUTION scale of 2 with size 2x3 r= random.pareto(a=2, size=(2, 3)) #RANDOM PARETO DISTRIBUTION shape of 2 with size 2x3 s = random.zipf(a=2, size=(2, 3)) #RANDOM ZIPF DISTRIBUTIONparameter 2 with size 2x3 ``` # NumPy Ufunc :::success :bulb: **Creating a ufunc** To create your own ufunc, you have to define a function, like you do with normal functions in Python, then you add it to your NumPy ufunc library with the frompyfunc() method. The frompyfunc() method takes the following arguments: 1. function - the name of the function. 2. inputs - the number of input arguments (arrays). 3. outputs - the number of output arrays. ::: :::success :bulb: **Rounding Decimals** There are primarily five ways of rounding off decimals in NumPy 1.Truncation 2.Fix 3.Rounding 4.Floor 5.Ceil ::: ```python! import numpy as np from numpy import random as rand x = [1,2,3] y = [4,5,6] z = [] a = [-1,0,-3,4] g = [0,0,0,1,1,0] b = rand.rand(5) *10 -5 for i, j in zip(x,y): #without ufunc, you can use zip() to add z.append(i + j) z = np.add(x,y) #array addition with ufunc! def myadd(x,y): #define ufunc return x+y myadd = np.frompyfunc(myadd,2,1) #creating your own addition ufunc print(type(np.add)) #validates that add is a ufunc if type(np.add) == np.ufunc: #checks if add is a ufunc print('add is ufunc') else: print('add is not ufunc') np.subtract(x,y) #array subtraction np.multiply(x,y) #array multiplication np.divide(x,y) #array division np.power(x,y) #array power of values np.remainder(x,y) #array remainder np.mod(x,y) #array modulus; same as remainder except for when there are negatives np.divmod(x,y) #returns both quotient(first array) and mod(second array) answers np.absolute(a) #absolute values the array print('array: ', b) print('truncate: ', np.trunc(b)) #chops off the decimal print('fix: ', np.fix(b)) #basically the same as truncating print('around: ', np.around(b)) #checks if decimal >=5 print('floor: ', np.floor(b)) #rounds down print('ceil: ', np.ceil(b)) #rounds up np.log2(x) #finds log at base 2 for each element; there's also log10 and log np.sum([x,y]) #sums everything into one value; also works with axis np.cumsum(x) #partial adding the elements in the array np.prod([x,y]) #multiplies everything into one value; works with axis; cumprod() np.diff(a, n=2)#subtracts two successive elements n num of times np.lcm(5,3) #finds the lowest common multiple btw two nums np.lcm.reduce(y) #finding the lcm of an array #same stuff for gcd print(np.pi) #look its pi pies = np.array([np.pi/2, np.pi/3, np.pi/4, np.pi/5]) print(np.sin(pies)) #sin, cos, tan, arcsin, arccos, arctan trig np functions! print(np.rad2deg(pies)) #convert rad to deg; np.deg2rad works too base = 3 perp = 4 p = np.hypot(base, perp) #Find the hypotenues for 4 base and 3 perpendicular np.sinh(np.pi/2) #hyperbolic trig sinh,cosh, tanh, arcsinh, arccosh, arctanh np.unique(g) #creates unique array (one digit only present once); only works with 1d one = np.array([1,1,1,2]) two = np.array([2,2,26]) np.union1d(one,two) #unique array with 2 arrays (only 2) np.intersect1d(one,two, assume_unique=True) #find values only present in both arrays np.setdiff1d(one,two, assume_unique=True) #present in the first array but not the second np.setxor1d(set1, set2, assume_unique=True) #not present in both arrays ``` # Brute Force with NumPy ```Python! import hashlib import numpy as np import string import time # Function to hash a password def hash_password(password): return hashlib.sha256(password.encode()).hexdigest() # Dictionary attack (optional) wordlist = np.array(["12345", "password", "admin", "qwerty"]) hashed_list = np.vectorize(hash_password)(wordlist) # User input password = input("Enter a password to simulate cracking: ").strip() target_hash = hash_password(password) # Brute-force function def brute_force(target_hash, max_len=4): charset = list(string.ascii_lowercase + string.digits) attempts = 0 start_time = time.time() while True: # Random length between 1 and max_len length = np.random.randint(1, max_len + 1) # Generate a random guess guess = ''.join(np.random.choice(charset, size=length)) guess_hash = hash_password(guess) attempts += 1 if guess_hash == target_hash: end_time = time.time() return attempts, guess, end_time - start_time # Run the brute-force attack attempts, cracked_password, duration = brute_force(target_hash, max_len=4) # Output print(f"\n✅ Password '{cracked_password}' cracked after {attempts} attempts in {duration:.2f} seconds.") ``` >[time=Mon, Jun 9, 2025] # Tensors Notes :::info :information_source: **Info** - Data Structures similar to arrays and matrices - Used for encoding inputs and outputs of a model - Similar to NumPy ndarrays, but tensors run on GPU and other hardware accelerators ::: ```python= import torch import numpy as np #CREATING TENSORS data = [[1,2],[3,4]] #directly from data x_data = torch.tensor(data) np_array = np.array(data) #from numpy arrays x_np = torch.from_numpy(np_array) #from other tensors x_ones = torch.ones_like(x_data) #retains properties of x_data; tensor filled with ones with x_data dimin x_rand = torch.rand_like(x_data, dtype = torch.float) #overrides datatype of x_data; random float tensor with x_daya dimin #with random or constant values shape = (2,3,) #this is a tuple in tensor dimensions rand_tensor = torch.rand(shape) #random tensor with shape dimin ones_tensor = torch.ones(shape) #tensor filled with ones in shape dimin zeros_tensor = torch.zeros(shape) #tensor filled with zeros in shape dimin #ATTRIBUTES OF A TENSOR tensor = torch.rand(3,4) tensor.shape #shape of the tensor tensor.dtype #data type of tensor tensor.device #device tensor stored on #OPERATIONS ON TENSORS if torch.cuda.is_available(): #check if cuda(gpu) is available device = torch.device("cuda") #indexing and slicing tensor = torch.randint(0, 10, (4,4), dtype=torch.int32) #random int tensor tensor = torch.ones(4,4) print(f"First row: {tensor[0]}") print(f"Last row: {tensor[-1,...]}") print(f"First column: {tensor[:,0]}") print(f"Last column: {tensor[...,-1]}") tensor[:,1] = 0 #joining tensors t1 = torch.cat([tensor,tensor,tensor], dim = 1) #dim is like axis #arithmetic operations #below is matrix multiplication, all y vars output the same #tensor.T returns the transpose of the tensor, swaps the two dimin or the last two dimin y1 = tensor @ tensor.T y2 = tensor.matmul(tensor.T) y3 = torch.rand_like(y1) torch.matmul(tensor, tensor.T, out=y3) #below is element-wise product, all z vars output the same z1 = tensor * tensor z2 = tensor.mul(tensor) z3 = torch.rand_like(z1) torch.mul(tensor, tensor, out=z3) #single-element tensors agg = torch.sum(tensor) #turns tensor into a single value agg_item = agg.item() #turns agg into python numerical value #in-place operations #operations that store the result into the operand are called in-place #denoted by _ suffix tensor.add_(5) #BRIDGE WITH NUMPY #tensors on the CPU and NumPy arrays can share their underlying memory locations, and changing one will change the other. #tensor to numpy array t = torch.ones(5) n = t.numpy() print(f"tensor: {t} ") print(f"numpy: {n}") t.add_(1) print(f"tensor after: {t} ") print(f"numpy after: {n}") #numpy array to tensor n = np.ones(5) t = torch.from_numpy(n) print(f"tensor: {t} ") print(f"numpy: {n}") np.add(n,1,out=n) print(f"tensor after: {t} ") print(f"numpy after: {n}") ``` >[time=Wed, Jun 11, 2025]