|
| 1 | +# 📦 NumPy Broadcasting and Vectorization |
| 2 | + |
| 3 | +This guide explains two core concepts in NumPy that enable high-performance array operations without the need for explicit Python loops: **Broadcasting** and **Vectorization**. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## 📘 Table of Contents |
| 8 | +1. Introduction |
| 9 | +2. Broadcasting |
| 10 | +3. Vectorization |
| 11 | +4. Key Differences |
| 12 | +5. Conclusion |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## 1. Introduction |
| 17 | + |
| 18 | +NumPy is optimized for fast numerical operations. Two of its most powerful features are: |
| 19 | +- **Broadcasting**: Automatically expanding dimensions to match arrays during operations. |
| 20 | +- **Vectorization**: Applying operations to entire arrays at once without explicit iteration. |
| 21 | + |
| 22 | +These help in writing concise, readable, and efficient code for large-scale data processing. |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## 2. 📡 Broadcasting |
| 27 | + |
| 28 | +Broadcasting allows NumPy to perform operations on arrays of different shapes, by automatically expanding the smaller array to match the shape of the larger one. |
| 29 | + |
| 30 | +### ✅ Example: |
| 31 | +```python |
| 32 | +import numpy as np |
| 33 | + |
| 34 | +arr = np.array([10, 13, 45, 79, 90]) |
| 35 | +discount = 10 |
| 36 | + |
| 37 | +# Applying scalar discount to each item in array |
| 38 | +# Equivalent to arr - (arr * 0.10) |
| 39 | +disc_arr = arr - (arr * (discount / 100)) |
| 40 | +print(disc_arr) |
| 41 | +# Output: [ 9. 11.7 40.5 71.1 81. ] |
| 42 | +``` |
| 43 | + |
| 44 | +### ✅ Broadcasting between 1D and 2D: |
| 45 | +```python |
| 46 | +arr_2d = np.array([[2, 3, 4, 8, 10], |
| 47 | + [5, 6, 7, 12, 4]]) |
| 48 | + |
| 49 | +# Broadcasting scalar 10 |
| 50 | +print(arr_2d + 10) |
| 51 | +# Output: |
| 52 | +# [[12 13 14 18 20] |
| 53 | +# [15 16 17 22 14]] |
| 54 | + |
| 55 | +# Broadcasting 1D array to 2D |
| 56 | +arr = np.array([10, 13, 45, 79, 90]) |
| 57 | +print(arr_2d + arr) |
| 58 | +# Output: |
| 59 | +# [[12 16 49 87 100] |
| 60 | +# [15 19 52 91 94]] |
| 61 | +``` |
| 62 | + |
| 63 | +### ❌ When shapes are not compatible: |
| 64 | +```python |
| 65 | +# This will raise an error because the shape [2, 5] and [2,] can't broadcast |
| 66 | +print(arr_2d + [2, 3]) |
| 67 | +# ValueError |
| 68 | +``` |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +## 3. ⚡ Vectorization |
| 73 | + |
| 74 | +Vectorization allows you to perform operations on entire arrays without using `for` loops. |
| 75 | + |
| 76 | +### ✅ Example: |
| 77 | +```python |
| 78 | +array1 = np.array([1, 2, 3]) |
| 79 | +array2 = np.array([4, 5, 6]) |
| 80 | + |
| 81 | +# Element-wise addition |
| 82 | +print(array1 + array2) # Output: [5 7 9] |
| 83 | + |
| 84 | +# Scalar multiplication |
| 85 | +print(array1 * 35) # Output: [35 70 105] |
| 86 | + |
| 87 | +# Modulo operation |
| 88 | +print(array2 % 3) # Output: [1 2 0] |
| 89 | + |
| 90 | +# Vectorized division of 2D array |
| 91 | +arr_2d = np.array([[2, 3, 4, 8, 10], |
| 92 | + [5, 6, 7, 12, 4]]) |
| 93 | +print(arr_2d / 2) |
| 94 | +# Output: |
| 95 | +# [[1. 1.5 2. 4. 5. ] |
| 96 | +# [2.5 3. 3.5 6. 2. ]] |
| 97 | +``` |
| 98 | + |
| 99 | +### ✅ Advantages: |
| 100 | +- Much faster than using loops |
| 101 | +- Less code = better readability |
| 102 | +- Takes advantage of underlying C implementations |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +## 4. 🔍 Key Differences |
| 107 | +| Feature | Broadcasting | Vectorization | |
| 108 | +|----------------|----------------------------------|----------------------------------------| |
| 109 | +| Definition | Auto-expanding shapes to match | Applying operations over entire arrays | |
| 110 | +| Requirement | Operands of different shapes | Arrays must support element-wise ops | |
| 111 | +| Use Case | Mixing scalars with arrays, etc. | Mathematical operations on arrays | |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +## 5. ✅ Conclusion |
| 116 | + |
| 117 | +With **broadcasting**, you can mix and match scalars and arrays. With **vectorization**, you can avoid slow `for` loops entirely. Combined, they make NumPy extremely powerful for numerical computing. |
| 118 | + |
| 119 | +Explore more in the [NumPy documentation](https://numpy.org/doc/stable/). |
| 120 | + |
0 commit comments