Python NumPy Library NumPy, the foundational open-source Python library for numerical computation, provides the N-dimensional array (ndarray) and underpins major data-science tools such as Pandas, SciPy, scikit-learn, and TensorFlow. The library offers a broad suite of array creation methods, properties, and manipulation techniques, including reshaping, flattening, and copy-versus-view semantics, as demonstrated in a practical tutorial. NumPy Numerical Python is a foundational open-source Python library for numerical and mathematical computation. It introduces the N-dimensional array ndarray , a high-performance data structure for storing and manipulating large datasets efficiently. NumPy forms the computational foundation of the Python data-science ecosystem; major libraries such as Pandas, SciPy, scikit-learn, and TensorFlow build directly upon it. This tutorial is designed to provide a concise yet practical overview of NumPy and to support day-to-day technical work through clear, task-oriented examples. NumPy provides a broad suite of tools for numerical computation, including: Using pip pip install numpy Using conda conda install numpy Using poetry poetry add numpy The following test script can be used to confirm that NumPy has been installed correctly. python import numpy as np Check NumPy version print f"NumPy version: {np. version }" NumPy version: 2.5.1 Ndarray creation This section demonstrates several standard methods for creating NumPy arrays. One-dimensional ndarray arr1d = np.array 1, 2, 3, 4, 5 print "From list:", arr1d From list: 1 2 3 4 5 Two-dimensional ndarray arr2d= np.array 1, 2, 3 , 4, 5, 6 print "\n2D array:\n", arr2d 2D array: 1 2 3 4 5 6 Zero-filled and one-filled arrays zeros = np.zeros 5 print "\nZeros:", zeros ones = np.ones 3, 3 print "\nOnes:\n", ones Zeros: 0. 0. 0. 0. 0. Ones: 1. 1. 1. 1. 1. 1. 1. 1. 1. Range-based and evenly spaced sequences range arr = np.arange 0, 10, 2 print "\nRange 0 to 10, step 2 :", range arr linspace arr = np.linspace 0, 10, 5 print "\nLinspace 0 to 10, 5 points :", linspace arr Range 0 to 10, step 2 : 0 2 4 6 8 Linspace 0 to 10, 5 points : 0. 2.5 5. 7.5 10. Identity and uninitialised arrays create 2D identity matrix identity = np.eye 3 print "\nIdentity matrix:\n", identity create 2D array with random garbage values, it is faster than random.rand and random.randn empty = np.empty 2, 2 print "\nEmpty array shape:", empty.shape Identity matrix: 1. 0. 0. 0. 1. 0. 0. 0. 1. Empty array shape: 2, 2 Randomly generated arrays create 2D array with random values between 0 and 1 random arr = np.random.rand 3, 3 print "\nRandom array 0-1 :\n", random arr create 2D array with random integers between 1 and 10 random int = np.random.randint 1, 10, size= 2, 3 print "\nRandom integers 1-10 :\n", random int Random array 0-1 : 0.55874991 0.81386435 0.31782834 0.39704509 0.89016825 0.82541621 0.10668708 0.15977588 0.65121931 Random integers 1-10 : 2 2 9 8 4 4 Ndarray properties and attributes Reference array arr = np.array 1, 2, 3 , 4, 5, 6 Array properties print "Shape:", arr.shape print "Dimensions:", arr.ndim print "Size total elements :", arr.size print "Data type:", arr.dtype print "Item size bytes :", arr.itemsize print "Strides:", arr.strides Shape: 2, 3 Dimensions: 2 Size total elements : 6 Data type: int64 Item size bytes : 8 Strides: 24, 8 Reshaping arrays reshaped = arr.reshape 3, 2 print "\nReshaped to 3, 2 :\n", reshaped Reshaped to 3, 2 : 1 2 3 4 5 6 Flattening arrays flattened = arr.flatten print "\nFlattened:", flattened Flattened: 1 2 3 4 5 6 Copy versus view arr copy = arr.copy arr view = arr.view arr copy 0, 0 = 999 print "\nOriginal:", arr 0, 0 print "Copy modified:", arr copy 0, 0 arr view 0, 0 = 888 print "Original after view modified:", arr 0, 0 print "View modified:", arr view 0, 0 Original: 1 Copy modified: 999 Original after view modified: 888 View modified: 888 A view is typically faster than creating a copy, but it shares underlying data with the original ndarray. Consequently, modifying values through a view also modifies the original array. Views are particularly useful when adjusting shape or data-type representations without duplicating data. Changing the shape of a view 1. Create a flat 1D original array original = np.array 10, 20, 30, 40, 50, 60 2. Create a view and change its dimensions to a 2x3 matrix matrix view = original.reshape 2, 3 3. Check the shapes print "Original Shape:", original.shape print "View Shape: ", matrix view.shape print "\nOriginal Array:\n", original print "\nMatrix View:\n", matrix view Original Shape: 6, View Shape: 2, 3 Original Array: 10 20 30 40 50 60 Matrix View: 10 20 30 40 50 60 Changing the data type representation of a view 1. Create a flat 1D original array original = np.array 10, 20, 30, 40, 50, 60 2. View the exact same memory bytes as 16-bit integers Because 16-bit is half the size of 64-bit, each number splits into four matrix view = original.view np.int16 3. Check the shapes print "Original dtype:", original.dtype print "View dtype: ", matrix view.dtype print "\nOriginal Array:\n", original print "\nMatrix View:\n", matrix view Original dtype: int64 View dtype: int16 Original Array: 10 20 30 40 50 60 Matrix View: 10 0 0 0 20 0 0 0 30 0 0 0 40 0 0 0 50 0 0 0 60 0 0 0 where conditions Reference arrays arr = np.arange 20 arr 2d = np.arange 24 .reshape 4, 6 print "Original 1D:", arr print "\n2D array:\n", arr 2d Original 1D: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2D array: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Basic indexing print "\nElement at index 5:", arr 5 print "Element at 0, 2 :", arr 2d 0, 2 print "First row:", arr 2d 0 print "Last column:", arr 2d :, -1 Element at index 5: 5 Element at 0, 2 : 2 First row: 0 1 2 3 4 5 Last column: 5 11 17 23 Boolean indexing mask = arr 10 & arr < 15 print "\nArr 10 and < 15:", arr mask Arr 10 and < 15: 11 12 13 14 Fancy indexing through explicit index selection indices = 0, 5, 10, 15 print "arr 0, 5, 10, 15 :", arr indices arr 0, 5, 10, 15 : 0 5 10 15 Slicing operations print "\narr 5:10 :", arr 5:10 print "arr ::2 :", arr ::2 Every 2nd element print "arr ::-1 :", arr ::-1 Reversed arr 5:10 : 5 6 7 8 9 arr ::2 : 0 2 4 6 8 10 12 14 16 18 arr ::-1 : 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Two-dimensional slicing print "\narr 2d 1:3, 2:5 :\n", arr 2d 1:3, 2:5 print "\narr 2d :, 1 :", arr 2d :, 1 All rows, column 1 arr 2d 1:3, 2:5 : 8 9 10 14 15 16 arr 2d :, 1 : 1 7 13 19 Conditional selection with where result = np.where arr 10, arr, 0 print "\nWhere arr 10:", result Where arr 10: 0 0 0 0 0 0 0 0 0 0 0 11 12 13 14 15 16 17 18 19 Unlike Python lists, NumPy applies operations across entire ndarrays. Reference arrays a = np.array 1, 2, 3, 4, 5 b = np.array 10, 20, 30, 40, 50 Basic arithmetic operations print "a + b:", a + b print "a - b:", a - b print "a b:", a b print "b / a:", b / a print "a 2:", a 2 a + b: 11 22 33 44 55 a - b: -9 -18 -27 -36 -45 a b: 10 40 90 160 250 b / a: 10. 10. 10. 10. 10. a 2: 1 4 9 16 25 Universal functions print "\nSquare root:", np.sqrt a print "Absolute value:", np.abs np.array -1, -2, 3 print "Exponential:", np.exp np.array 1, 2, 3 print "Logarithm:", np.log np.array 1, 2.718, 10 Square root: 1. 1.41421356 1.73205081 2. 2.23606798 Absolute value: 1 2 3 Exponential: 2.71828183 7.3890561 20.08553692 Logarithm: 0. 0.99989632 2.30258509 Trigonometric functions angles = np.array 0, np.pi/4, np.pi/2, np.pi print "\nSine:", np.sin angles print "Cosine:", np.cos angles print "Tangent:", np.tan angles Sine: 0.00000000e+00 7.07106781e-01 1.00000000e+00 1.22464680e-16 Cosine: 1.00000000e+00 7.07106781e-01 6.12323400e-17 -1.00000000e+00 Tangent: 0.00000000e+00 1.00000000e+00 1.63312394e+16 -1.22464680e-16 Rounding functions decimals = np.array 1.234, 5.678, 2.567 print "\nCeiling:", np.ceil decimals print "Floor:", np.floor decimals print "Round:", np.round decimals, 2 Ceiling: 2. 6. 3. Floor: 1. 5. 2. Round: 1.23 5.68 2.57 Reference arrays arr = np.array 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 arr 2d = np.arange 1, 13 .reshape 3, 4 Basic descriptive statistics print "Sum:", np.sum arr print "Mean:", np.mean arr print "Median:", np.median arr print "Std Dev:", np.std arr print "Variance:", np.var arr Sum: 55 Mean: 5.5 Median: 5.5 Std Dev: 2.8722813232690143 Variance: 8.25 Axis-wise statistics 2D example print "\n2D array:\n", arr 2d print "\nSum along axis 0 columns :", np.sum arr 2d, axis=0 print "Sum along axis 1 rows :", np.sum arr 2d, axis=1 print "Mean along axis 0:", np.mean arr 2d, axis=0 print "Mean along axis 1:", np.mean arr 2d, axis=1 2D array: 1 2 3 4 5 6 7 8 9 10 11 12 Sum along axis 0 columns : 15 18 21 24 Sum along axis 1 rows : 10 26 42 Mean along axis 0: 5. 6. 7. 8. Mean along axis 1: 2.5 6.5 10.5 Minimum and maximum functions print "\nMin:", np.min arr print "Max:", np.max arr print "Argmin index :", np.argmin arr print "Argmax index :", np.argmax arr Min: 1 Max: 10 Argmin index : 0 Argmax index : 9 Percentiles print "\n25th percentile:", np.percentile arr, 25 print "50th percentile median :", np.percentile arr, 50 print "75th percentile:", np.percentile arr, 75 25th percentile: 3.25 50th percentile median : 5.5 75th percentile: 7.75 Cumulative operations print "\nCumulative sum:", np.cumsum arr :5 print "Cumulative product:", np.cumprod np.array 1, 2, 3, 4 print "Cumulative max:", np.maximum.accumulate np.array 1, 3, 2, 5, 4 Cumulative sum: 1 3 6 10 15 Cumulative product: 1 2 6 24 Cumulative max: 1 3 3 5 5 Reference arrays a = np.array 1, 2, 3 b = np.array 4, 5, 6 c = np.array 6, 7, 8, , 9, 10, 11 Concatenation concat = np.concatenate a, b print "Concatenate:", concat Concatenate: 1 2 3 4 5 6 stack , hstack , and vstack stacked = np.stack a, b print "\nStack:\n", stacked horizontal hstacked = np.hstack a, b print "\nHStack:", hstacked vertical vstacked = np.vstack a , b print "\nVStack:\n", vstacked Stack: 1 2 3 4 5 6 HStack: 1 2 3 4 5 6 VStack: 1 2 3 4 5 6 Splitting arrays arr = np.arange 10 split result = np.array split arr, 3 print "\nArray split into 3 parts:" for i, part in enumerate split result : print f" Part {i}: {part}" Array split into 3 parts: Part 0: 0 1 2 3 Part 1: 4 5 6 Part 2: 7 8 9 Transposition print "\nOriginal:\n", c print "Transposed:\n", c.T Original: 6 7 8 9 10 11 Transposed: 6 9 7 10 8 11 Unique values arr with dupes = np.array 1, 2, 2, 3, 3, 3, 4 print "\nUnique values:", np.unique arr with dupes Unique values: 1 2 3 4 Sorting arr unsorted = np.array 3, 1, 4, 1, 5, 9, 2, 6 print "Sorted:", np.sort arr unsorted print "Argsort indices :", np.argsort arr unsorted Sorted: 1 1 2 3 4 5 6 9 Argsort indices : 1 3 6 0 2 4 7 5 Dot product and matrix multiplication 1d ndarrays a = np.array 1, 2, 3 b = np.array 4, 5, 6 dot product = np.dot a, b print "Dot product:", dot product 1 4 + 2 5 + 3 6 = 32 2d ndarrays mat a = np.array 1, 5 , 3, 4 mat b = np.array 5, 6 , 7, 8 matrix product = np.dot mat a, mat b print "\nMatrix product:\n", matrix product Using the @ operator for matrix multiplication matrix product operator = mat a @ mat b print "\nMatrix product using @ operator:\n", matrix product operator Dot product: 32 Matrix product: 40 46 43 50 Matrix product using @ operator: 40 46 43 50 Trace sum of diagonal elements print "Trace:", np.trace mat a Trace: 5 linalg : linear algebra submodule Determinant det = np.linalg.det mat a print "\nDeterminant:", det Inverse inv = np.linalg.inv mat a print "\nInverse:\n", inv Eigenvalues and eigenvectors eigenvalues, eigenvectors = np.linalg.eig mat a print "\nEigenvalues:", eigenvalues print "Eigenvectors:\n", eigenvectors Rank print "\nRank:", np.linalg.matrix rank mat a Norm print "\nNorm default :", np.linalg.norm a print "Norm L2 :", np.linalg.norm a, ord=2 print "Norm L1 :", np.linalg.norm a, ord=1 Determinant: -11.000000000000002 Inverse: -0.36363636 0.45454545 0.27272727 -0.09090909 Eigenvalues: -1.65331193+0.j 6.65331193+0.j Eigenvectors: -0.88333068+0.j -0.66249905+0.j 0.46875037+0.j -0.74906275+0.j Rank: 2 Norm default : 3.7416573867739413 Norm L2 : 3.7416573867739413 Norm L1 : 6.0 Broadcasting enables operations on ndarrays with different shapes, provided that their dimensions are compatible. Array and scalar broadcasting arr = np.array 1, 2, 3, 4, 5 result = arr + 10 print "Array + scalar:", result Array + scalar: 11 12 13 14 15 One-dimensional and two-dimensional ndarray broadcasting arr 1d = np.array 1, 2, 3 arr 2d = np.array 10 , 20 , 30 result = arr 1d + arr 2d print "\n1D + 2D broadcasting :" print "Shape 3, + 3, 1 = 3, 3 " print result 1D + 2D broadcasting : Shape 3, + 3, 1 = 3, 3 11 12 13 21 22 23 31 32 33 Operations across dimensions matrix = np.array 1, 2, 3 , 4, 5, 6 , 7, 8, 9 column = np.array 10, 20, 30 print "\nSubtract column from matrix:" print matrix - column Subtract column from matrix: -9 -18 -27 -6 -15 -24 -3 -12 -21 Broadcasting rules: Broadcasting rules: examples php Shape 5, broadcasts with 3, 5 - 3, 5 Shape 3, 1 broadcasts with 3, 4 - 3, 4 Shape 1, 5 broadcasts with 3, 5 - 3, 5 Set seed for reproducibility np.random.seed 1000 For reproducibility Uniform distribution on 0, 1 uniform = np.random.rand 5 print "Uniform 0, 1 :", uniform Uniform 0, 1 : 0.65358959 0.11500694 0.95028286 0.4821914 0.87247454 Random integers ints = np.random.randint 1, 10, size=5 print "Random integers 1, 10 :", ints Random integers 1, 10 : 9 5 5 5 3 Normal Gaussian distribution normal = np.random.randn 5 print "Normal distribution:", normal Normal distribution: 0.57363145 -0.74841131 -0.4122031 -0.07400906 -0.92893693 Normal distribution with custom mean and standard deviation custom normal = np.random.normal loc=100, scale=15, size=5 print "\nNormal μ=100, σ=15 :", custom normal Normal μ=100, σ=15 : 120.85092205 117.92603993 110.61013587 114.8944316 102.09195908 Exponential distribution exponential = np.random.exponential scale=2.0, size=5 print "Exponential λ=0.5 :", exponential Exponential λ=0.5 : 4.69093541 0.02095277 0.1549649 0.56109307 0.28613573 Random choice from an ndarray arr = np.arange 10 choices = np.random.choice arr, size=5, replace=False print "\nRandom choice no replace :", choices Random choice no replace : 4 2 8 0 3 In-place shuffling arr = np.arange 10 np.random.shuffle arr print "Shuffled:", arr Shuffled: 4 9 5 1 3 6 2 0 8 7 Shuffling with a copied permutation arr = np.arange 10 shuffled = np.random.permutation arr print "Permutation:", shuffled Permutation: 2 8 7 1 4 0 5 6 9 3 Binomial distribution binomial = np.random.binomial n=10, p=0.5, size=5 print "\nBinomial n=10, p=0.5 :", binomial Binomial n=10, p=0.5 : 6 4 5 5 5 Setup code python import os import tempfile import numpy as np Create sample array arr = np.array 1, 2, 3 , 4, 5, 6 , 7, 8, 9 Create temp directory for demo temp dir = tempfile.mkdtemp print f"original ndarray: {arr}" print f"Temporary directory created at: {temp dir}" original ndarray: 1 2 3 4 5 6 7 8 9 Temporary directory created at: /tmp/tmpr0nzny9i Save in .npy format binary npy path = os.path.join temp dir, 'array.npy' np.save npy path, arr print f"Saved .npy file to {npy path}" Saved .npy file to /tmp/tmpr0nzny9i/array.npy Load .npy file loaded arr = np.load npy path print "Loaded from .npy:\n", loaded arr Loaded from .npy: 1 2 3 4 5 6 7 8 9 Save multiple arrays as .npz compressed npz path = os.path.join temp dir, 'arrays.npz' arr2 = np.array 10, 20, 30, 40 np.savez npz path, array1=arr, array2=arr2 print f"\nSaved .npz file to {npz path}" Saved .npz file to /tmp/tmpr0nzny9i/arrays.npz Load .npz file loaded = np.load npz path print "Loaded from .npz:" print " array1:\n", loaded 'array1' print " array2:", loaded 'array2' Loaded from .npz: array1: 1 2 3 4 5 6 7 8 9 array2: 10 20 30 40 Save as a text file CSV-like format txt path = os.path.join temp dir, 'array.txt' np.savetxt txt path, arr, delimiter=',', fmt='%d' print f"\nSaved text file to {txt path}" Saved text file to /tmp/tmpr0nzny9i/array.txt Load from a text file loaded txt = np.loadtxt txt path, delimiter=',' print "Loaded from text:\n", loaded txt Loaded from text: 1. 2. 3. 4. 5. 6. 7. 8. 9. Apply a function to each element arr = np.array 1, 2, 3, 4, 5 squared = np.vectorize lambda x: x 2 arr print "Vectorized function square :", squared Vectorized function square : 1 4 9 16 25 Piecewise operations arr = np.array 1, 2, 3, 4, 5 result = np.piecewise arr, arr < 3, arr = 3 , lambda x: x 2, lambda x: x 10 print "\nPiecewise x<3: x², x≥3: 10x :", result Piecewise x<3: x², x≥3: 10x : 1 4 30 40 50 Apply operations along an axis matrix = np.array 1, 2, 3 , 4, 5, 6 sums0 = np.apply along axis np.sum, axis=0, arr=matrix sums1 = np.apply along axis np.sum, axis=1, arr=matrix print "\nApply sum along axis 0:", sums0 print "Apply sum along axis 1:", sums1 Apply sum along axis 0: 5 7 9 Apply sum along axis 1: 6 15 Repeat and tile arr = np.array 1, 2, 3 print "\nRepeat each element 2 times :", np.repeat arr, 2 print "Tile whole array 2 times :", np.tile arr, 2 Repeat each element 2 times : 1 1 2 2 3 3 Tile whole array 2 times : 1 2 3 1 2 3 Reduction operations arr = np.array 1, 2, 3, 4, 5 result = np.add.reduce arr Sum print "\nReduce with add sum :", result Reduce with add sum : 15 searchsorted binary search sorted arr = np.array 1, 3, 5, 7, 9 indices = np.searchsorted sorted arr, 2, 4, 6, 8 print "\nSearchsorted indices:", indices Searchsorted indices: 1 2 3 4 Extract diagonal elements matrix = np.arange 9 .reshape 3, 3 diagonal0 = np.diag matrix, k=0 Main diagonal diagonal1 = np.diag matrix, k=1 Diagonal above main print "\nDiagonal of matrix:\n", matrix print "Diagonal elements:", diagonal0 print "Diagonal above main:", diagonal1 Diagonal of matrix: 0 1 2 3 4 5 6 7 8 Diagonal elements: 0 4 8 Diagonal above main: 1 5 Create a diagonal matrix diag matrix = np.diag 1, 2, 3 print "\nDiagonal matrix from 1, 2, 3 :\n", diag matrix Diagonal matrix from 1, 2, 3 : 1 0 0 0 2 0 0 0 3 Count and display non-zero values arr = np.array 0, 1, 0, 2, 3, 0 print "\nNonzero count:", np.count nonzero arr print "Nonzero indices:", np.nonzero arr Nonzero count: 3 Nonzero indices: array 1, 3, 4 , Setup code python import time Avoid Python loops by using vectorisation arr = np.arange 1 000 000 Slow: Python loop start = time.time result = np.array x 2 for x in arr loop time = time.time - start print f"Python loop: {loop time:.6f} seconds" Fast: NumPy vectorization start = time.time result = arr 2 vectorized time = time.time - start print f"NumPy vectorized: {vectorized time:.6f} seconds" print f"Speedup: {loop time/vectorized time:.1f}x faster\n" === Performance: Vectorization === Python loop: 0.238411 seconds NumPy vectorized: 0.001625 seconds Speedup: 146.7x faster Use in-place operations where appropriate arr = np.arange 5 print "Original:", arr arr += 10 In-place more memory efficient print "After += 10:", arr Original: 0 1 2 3 4 After += 10: 10 11 12 13 14 Data types and memory usage arr float64 = np.arange 1000, dtype=np.float64 arr float32 = np.arange 1000, dtype=np.float32 arr int32 = np.arange 1000, dtype=np.int32 print f"Float64: {arr float64.nbytes} bytes" print f"Float32: {arr float32.nbytes} bytes" print f"Int32: {arr int32.nbytes} bytes" Float64: 8000 bytes Float32: 4000 bytes Int32: 4000 bytes Memory efficiency: views versus copies original = np.arange 10 view = original : This is a view, shares memory copy = original : .copy This is a copy print f"View shares memory: {view.base is original}" print f"Copy doesn't share memory: {copy.base is original}" View shares memory: True Copy doesn't share memory: False Useful diagnostics for debugging arr = np.random.randn 3, 4, 5 print f"Shape: {arr.shape}" print f"Ndim: {arr.ndim}" print f"Dtype: {arr.dtype}" print f"Size: {arr.size}" print f"Memory: {arr.nbytes} bytes" Shape: 3, 4, 5 Ndim: 3 Dtype: float64 Size: 60 Memory: 480 bytes Check for NaN and infinite values arr = np.array 1, 2, np.nan, 4, np.inf, -np.inf print f"Array: {arr}" print f"Has NaN: {np.isnan arr .any }" print f"Has Inf: {np.isinf arr .any }" print f"Is finite: {np.isfinite arr }" Array: 1. 2. nan 4. inf -inf Has NaN: True Has Inf: True Is finite: True True False True False False Type casting arr = np.array 1.5, 2.7, 3.2 print f"Original float : {arr}" print f"As int: {arr.astype int }" print f"As str: {arr.astype str }" Original float : 1.5 2.7 3.2 As int: 1 2 3 As str: '1.5' '2.7' '3.2' NumPy is a core component of scientific computing in Python. This tutorial has outlined how NumPy arrays differ from Python lists, how they can be created and inspected, and how indexing, arithmetic, and statistical operations can be performed efficiently. A key strength of NumPy lies in its speed and vectorised programming model. Rather than relying on explicit Python loops for every calculation, practitioners can apply concise operations to complete datasets. This capability makes NumPy an essential tool for data analysis, machine learning, and numerical modelling. To develop proficiency, practise regularly with arrays of different shapes, slicing patterns, and reshaping strategies. Comparing NumPy workflows with equivalent pure-Python approaches is particularly useful for understanding performance and expressiveness benefits. These foundations also support more advanced work with libraries such as Pandas, SciPy, and TensorFlow. This article has presented a concise, practice-oriented reference for fundamental NumPy workflows. For continued development, readers are encouraged to extend these examples to domain-specific datasets and to evaluate computational trade-offs in realistic analytical pipelines. Did this article help you? Let me know in the comments below, and don't forget to drop a like if you enjoyed the read Thank you.