For a comprehensive introcution of NumPy, refer to:

**Element-wise Operations**

One of NumPy’s strengths is its ability to perform operations on entire lists (or arrays) at once.

Let me introduce basic operations using this arrays as an example.

```
import numpy as np
array1 = np.array([1, 2, 3])
array2 = np.array([4, 5, 6])
```

**Addition**

```
result = array1 + array2
print(result) # Outputs [5, 7, 9]
```

**Subtraction**

```
result = array1 - array2
print(result) # Outputs [-3, -3, -3]
```

**Multiplication & Division**

Similarly, `array1 * array2`

and `array1 / array2`

work element-wise.

```
result1 = array1 * array2
print(result1) # Outputs [4 10 18]
result2 = array1 / array2
Print(result2) # Outputs [0.25 0.4 0.5]
```

**Python vs. Numpy**

In standard Python, `list1 = [1,2,3]`

and `list2 = [4,5,6]`

would concatenate with `list1 + list2`

to give

. **[1,2,3,4,5,6]**

But in NumPy, it adds element-wise to produce `[5,7,9]`

.

**Broadcasting in Numpy**

NumPy’s broadcasting is like a superpower. It lets you perform operations on arrays of different shapes.

**What is Broadcasting?**

It’s NumPy’s way of allowing operations on mismatched arrays by** virtually expanding the smaller array.**

**Examples of Broadcasting**

Here’s a simple example.

```
array = np.array([1, 2, 3])
result = array + 5
print(result) # Outputs [6, 7, 8]
```

Here’s another example.

```
prices = np.array([10, 20, 30])
discounted_prices = prices * 0.9
```

Now, `discounted_prices`

holds the values `[9, 18, 27]`

, which are the prices after applying a 10% discount.

And here’s another advanced example.

```
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
combined = x + y
# Result:
# [[5, 6, 7],
# [6, 7, 8],
# [7, 8, 9]]
```

**Mathematical Functions**

NumPy isn’t just about basic arithmetic. It offers a plethora of mathematical functions.

**Power and Logarithm**

```
numbers = np.array([2, 3, 4])
squared = np.square(numbers) # Result: [4, 9, 16]
logarithm = np.log(numbers) # Result: [0.6931, 1.0986, 1.3862]
```

**Trigonometry**

```
angles = np.array([0, np.pi/2, np.pi])
sine_values = np.sin(angles) # Result: [0., 1., 0.]
```

**Statistical Functions**

```
data = np.array([1, 2, 3, 4, 5])
mean = np.mean(data) # Result: 3.0
median = np.median(data) # Result: 3.0
```

**Array Manipulation**

Sometimes, you’ll want to reshape or tweak your arrays for various tasks.

**Reshaping Arrays**

```
original = np.array([1, 2, 3, 4, 5, 6])
reshaped = original.reshape(2, 3)
# Result:
# [[1, 2, 3],
# [4, 5, 6]]
```

**Flattening Arrays**

```
reshaped = [[1, 2, 3],[4, 5, 6]]
flattened = reshaped.flatten() # Result: [1, 2, 3, 4, 5, 6]
```

**Stacking & Splitting**

```
array1 = np.array([1, 2])
array2 = np.array([3, 4])
stacked = np.vstack((array1, array2))
# Result:
# [[1, 2],
# [3, 4]]
```

**Comparisons and Masks**

NumPy allows for element-wise comparisons, which can be super handy!

**Basic Comparisons**

```
a = np.array([1, 2, 3])
b = np.array([1, 0, 3])
comparison = a > b # Result: [False, True, False]
```

**Using Masks**

```
a = np.array([1, 2, 3])
mask = a > 2
filtered = a[mask] # Result: [3]
```

**Advanced Indexing**

NumPy offers more than just basic indexing. Let’s explore!

**Integer Indexing**

```
a = np.array([[1, 2], [3, 4], [5, 6]])
result = a[[0, 1, 2], [0, 1, 0]] # Result: [1, 4, 5]
```

`a[0, 0]`

selects the element in the first row and first column, which is`1`

.`a[1, 1]`

selects the element in the second row and second column, which is`4`

.`a[2, 0]`

selects the element in the third row and first column, which is`5`

.

**Boolean Indexing**

```
bool_idx = (a > 2)
filtered = a[bool_idx] # Result: [3, 4, 5, 6]
```

**Saving and Loading Arrays**

After all your hard work, you’ll want to save your arrays. Here’s how!

**Saving Arrays**

The `np.save()`

function in NumPy is used to save an array to a binary file in `.npy`

format.

`np.save('my_array', a)`

**Save the Array**: The array`a`

is saved to a file.**File Name and Format**: The file is named ‘my_array.npy’. The`.npy`

extension indicates that the file is in a binary format specifically designed for saving and loading NumPy arrays.**Location**: The file ‘my_array.npy’ will be saved in the current working directory, unless a specific path is provided.

**Loading Arrays**

`loaded_array = np.load('my_array.npy')`