... | ... | @@ -113,7 +113,7 @@ NumPy arrays can be... |
|
|
print()
|
|
|
```
|
|
|
|
|
|
- Created from a Python List of `int`s
|
|
|
- Created from a Python List of `int`-s
|
|
|
|
|
|
```python
|
|
|
python_list = [2, 4, 8, 16, 32, 64]
|
... | ... | @@ -122,7 +122,7 @@ NumPy arrays can be... |
|
|
print()
|
|
|
```
|
|
|
|
|
|
- Created from a Python List of `floats`s
|
|
|
- Created from a Python List of `float`-s
|
|
|
|
|
|
```python
|
|
|
python_list = [2., 4., 8., 16., 32., 64.]
|
... | ... | @@ -134,6 +134,22 @@ NumPy arrays can be... |
|
|
|
|
|
## Broadcasting
|
|
|
|
|
|
The next couple snippets are extracted from
|
|
|
[braodcasting.py](https://git-community.cs.odu.edu/tkennedy/python-workshop/-/blob/master/NumPy/broadcasting.py).
|
|
|
|
|
|
In Python... each element of a list must be updated one at a time. If a list of
|
|
|
prices needed to be reduced by 10%, each one would need to be multiplied by 0.9
|
|
|
within a loop...
|
|
|
|
|
|
```python
|
|
|
prices = [1.00, 2.95, 8.40, 3.50, 3.30, 16.91]
|
|
|
|
|
|
for idx in range(len(prices)):
|
|
|
price[idx] *= 0.9
|
|
|
```
|
|
|
|
|
|
or using a [list comprehension](Python-Workshop#loops-and-listgenerator-comprehensions)...
|
|
|
|
|
|
```python
|
|
|
prices = [1.00, 2.95, 8.40, 3.50, 3.30, 16.91]
|
|
|
prices = [0.9 * price for price in prices]
|
... | ... | @@ -141,6 +157,8 @@ NumPy arrays can be... |
|
|
print(prices)
|
|
|
```
|
|
|
|
|
|
NumPy's broadcasting mechanic allows us to write a simple `prices *= 0.9`.
|
|
|
|
|
|
```python
|
|
|
prices = np.array([1.00, 2.95, 8.40, 3.50, 3.30, 16.91])
|
|
|
prices *= 0.9
|
... | ... | @@ -152,36 +170,54 @@ NumPy arrays can be... |
|
|
print()
|
|
|
```
|
|
|
|
|
|
The obvious benefit is less typing. The more important one is optimization.
|
|
|
NumPy's core is implemented in C. The official NumPy Documentation provides a
|
|
|
succinct overview in its [Why is NumPy
|
|
|
Fast?](https://numpy.org/doc/stable/user/whatisnumpy.html#why-is-numpy-fast)
|
|
|
section.
|
|
|
|
|
|
How much faster is NumPy? Let us run a quick using [benchmark_broadcasting.py](https://git-community.cs.odu.edu/tkennedy/python-workshop/-/blob/master/NumPy/benchmark_broadcasting.py).
|
|
|
|
|
|
```python
|
|
|
num_values = 1000000
|
|
|
num_runs = 100
|
|
|
|
|
|
def op_wrapper_py():
|
|
|
prices = range(1, 1000000, 1)
|
|
|
prices = range(1, num_values, 1)
|
|
|
prices = [0.9 * price for price in prices]
|
|
|
|
|
|
py_list = timeit.timeit(op_wrapper_py, number=100)
|
|
|
py_list = timeit.timeit(op_wrapper_py, number=num_runs)
|
|
|
|
|
|
def op_wrapper_np():
|
|
|
prices = np.arange(0, 1000000, 1, dtype=np.float64)
|
|
|
prices = np.arange(0, num_values, 1, dtype=np.float64)
|
|
|
prices[:] *= 0.9
|
|
|
|
|
|
np_array = timeit.timeit(op_wrapper_np, number=100)
|
|
|
np_array = timeit.timeit(op_wrapper_np, number=num_runs)
|
|
|
|
|
|
print(f"Python Time: {py_list:.4f}")
|
|
|
print(f"NumPy Time : {np_array:.4f}")
|
|
|
```
|
|
|
|
|
|
On a Core i7-6700k... For 1 million numbers, run 100 times... The NumPy code is almost
|
|
|
10 times faster than the pure Python code.
|
|
|
|
|
|
**I/O**
|
|
|
| | Time |
|
|
|
| :--- | ---: |
|
|
|
| Python | 5.1248 |
|
|
|
| NumPy | 0.3168 |
|
|
|
|
|
|
**Indexing**
|
|
|
|
|
|
**Index Arrays**
|
|
|
## Remaining Topics
|
|
|
|
|
|
**Boolean (Mask) Index Arrays**
|
|
|
There are a few more topics to introduce:
|
|
|
|
|
|
- **Indexing** - will be covered as part of the Matrix Solver example
|
|
|
- **I/O**
|
|
|
- **Index Arrays**
|
|
|
- **Boolean (Mask) Index Arrays**
|
|
|
|
|
|
# Fun Examples!
|
|
|
|
|
|
The examples in this section are fun!
|
|
|
# Implementing a Matrix Solver
|
|
|
|
|
|
|
|
|
## Linear Algebra
|
... | ... | |