Skip to content

Commit 62a40ad

Browse files
committed
A lot of changes in NumPy
1 parent a162928 commit 62a40ad

File tree

2 files changed

+79
-73
lines changed

2 files changed

+79
-73
lines changed

README.md

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,18 +2559,10 @@ Profiling
25592559
---------
25602560
### Stopwatch
25612561
```python
2562-
from time import time
2563-
start_time = time() # Seconds since the Epoch.
2564-
...
2565-
duration = time() - start_time
2566-
```
2567-
2568-
#### High performance:
2569-
```python
25702562
from time import perf_counter
2571-
start_time = perf_counter() # Seconds since the restart.
2563+
start_time = perf_counter()
25722564
...
2573-
duration = perf_counter() - start_time
2565+
duration_in_seconds = perf_counter() - start_time
25742566
```
25752567

25762568
### Timing a Snippet
@@ -2614,8 +2606,9 @@ Line # Mem usage Increment Line Contents
26142606
### Call Graph
26152607
#### Generates a PNG image of the call graph with highlighted bottlenecks:
26162608
```python
2617-
# $ pip3 install pycallgraph2; brew/apt install graphviz
2609+
# $ pip3 install pycallgraph2; apt/brew install graphviz
26182610
import pycallgraph2 as cg, datetime
2611+
26192612
filename = f'profile-{datetime.datetime.now():%Y%m%d%H%M%S}.png'
26202613
drawer = cg.output.GraphvizOutput(output_file=filename)
26212614
with cg.PyCallGraph(drawer):
@@ -2633,62 +2626,70 @@ import numpy as np
26332626
```
26342627

26352628
```python
2636-
<array> = np.array(<list/list_of_lists>)
2637-
<array> = np.arange(from_inclusive, to_exclusive, ±step_size)
2638-
<array> = np.ones(<shape>)
2639-
<array> = np.random.randint(from_inclusive, to_exclusive, <shape>)
2629+
<array> = np.array(<list/list_of_lists>) # Returns 1d/2d NumPy array.
2630+
<array> = np.zeros/ones(<shape>) # Also np.full(<shape>, <el>).
2631+
<array> = np.arange(from_inc, to_exc, ±step) # Also np.linspace(start, stop, num).
2632+
<array> = np.random.randint(from_inc, to_exc, <shape>) # Also np.random.random(<shape>).
26402633
```
26412634

26422635
```python
2643-
<array>.shape = <shape>
2644-
<view> = <array>.reshape(<shape>)
2645-
<view> = np.broadcast_to(<array>, <shape>)
2636+
<view> = <array>.reshape(<shape>) # Also `<array>.shape = <shape>`.
2637+
<array> = <array>.flatten() # Collapses array into one dimension.
2638+
<view> = <array>.squeeze() # Removes dimensions of length one.
26462639
```
26472640

26482641
```python
2649-
<array> = <array>.sum(axis)
2650-
indexes = <array>.argmin(axis)
2642+
<array> = <array>.sum/min/mean/var/std(axis) # Passed dimension gets aggregated.
2643+
<array> = <array>.argmin(axis) # Returns indexes of smallest elements.
2644+
<array> = np.apply_along_axis(<func>, axis, <array>) # Func can return a scalar or array.
26512645
```
26522646

2653-
* **Shape is a tuple of dimension sizes.**
2654-
* **Axis is an index of the dimension that gets aggregated. Leftmost dimension has index 0.**
2647+
* **Shape is a tuple of dimension sizes. A 100x50 RGB image has shape (50, 100, 3).**
2648+
* **Axis is an index of the dimension that gets aggregated. Leftmost/outermost dimension has index 0. Summing a 100x50 RGB image along the axis 2 will return a greyscale image with shape (50, 100).**
2649+
* **Passing a tuple of axes will chain the operations like this: `'<array>.<method>(axis_1, keepdims=True).<method>(axis_2).squeeze()'`.**
26552650

26562651
### Indexing
26572652
```bash
2658-
<el> = <2d_array>[row_index, column_index]
2659-
<1d_view> = <2d_array>[row_index]
2660-
<1d_view> = <2d_array>[:, column_index]
2653+
<el> = <2d_array>[row_index, column_index] # <3d_a>[table_i, row_i, column_i]
2654+
<1d_view> = <2d_array>[row_index] # <3d_a>[table_i, row_i]
2655+
<1d_view> = <2d_array>[:, column_index] # <3d_a>[table_i, :, column_i]
26612656
```
26622657

26632658
```bash
2664-
<1d_array> = <2d_array>[row_indexes, column_indexes]
2665-
<2d_array> = <2d_array>[row_indexes]
2666-
<2d_array> = <2d_array>[:, column_indexes]
2659+
<1d_array> = <2d_array>[row_indexes, column_indexes] # <3d_a>[table_is, row_is, column_is]
2660+
<2d_array> = <2d_array>[row_indexes] # <3d_a>[table_is, row_is]
2661+
<2d_array> = <2d_array>[:, column_indexes] # <3d_a>[table_is, :, column_is]
26672662
```
26682663

26692664
```bash
2670-
<2d_bools> = <2d_array> ><== <el>
2671-
<1d_array> = <2d_array>[<2d_bools>]
2665+
<2d_bools> = <2d_array> ><== <el> # <3d_array> ><== <1d_array>
2666+
<1d_array> = <2d_array>[<2d_bools>] # <3d_array>[<2d_bools>]
26722667
```
2668+
* **All examples also allow assignments.**
26732669

26742670
### Broadcasting
26752671
**Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.**
26762672

26772673
```python
2678-
left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
2679-
right = [ 0.1 , 0.6 , 0.8 ] # Shape: (3)
2674+
left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
2675+
right = [ 0.1 , 0.6 , 0.8 ] # Shape: (3,)
26802676
```
26812677

26822678
#### 1. If array shapes differ in length, left-pad the shorter shape with ones:
26832679
```python
2684-
left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
2685-
right = [[0.1 , 0.6 , 0.8]] # Shape: (1, 3) <- !
2680+
left = [[0.1], [0.6], [0.8]] # Shape: (3, 1)
2681+
right = [[0.1 , 0.6 , 0.8]] # Shape: (1, 3) <- !
26862682
```
26872683

26882684
#### 2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:
26892685
```python
2690-
left = [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6], [0.8, 0.8, 0.8]] # Shape: (3, 3) <- !
2691-
right = [[0.1, 0.6, 0.8], [0.1, 0.6, 0.8], [0.1, 0.6, 0.8]] # Shape: (3, 3) <- !
2686+
left = [[0.1, 0.1, 0.1], # Shape: (3, 3) <- !
2687+
[0.6, 0.6, 0.6],
2688+
[0.8, 0.8, 0.8]]
2689+
2690+
right = [[0.1, 0.6, 0.8], # Shape: (3, 3) <- !
2691+
[0.1, 0.6, 0.8],
2692+
[0.1, 0.6, 0.8]]
26922693
```
26932694

26942695
#### 3. If neither non-matching dimension has size 1, raise an error.

index.html

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
<body>
5656
<header>
57-
<aside>July 18, 2022</aside>
57+
<aside>July 20, 2022</aside>
5858
<a href="https://gto76.github.io" rel="author">Jure Šorn</a>
5959
</header>
6060

@@ -2096,19 +2096,13 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment
20962096
{<span class="hljs-string">'team'</span>: <span class="hljs-string">'arsenal f.c.'</span>, <span class="hljs-string">'odds'</span>: [<span class="hljs-number">2.09</span>, <span class="hljs-number">3.74</span>, <span class="hljs-number">3.68</span>]}
20972097
</code></pre></div>
20982098

2099-
<div><h2 id="profiling"><a href="#profiling" name="profiling">#</a>Profiling</h2><div><h3 id="stopwatch">Stopwatch</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> time
2100-
start_time = time() <span class="hljs-comment"># Seconds since the Epoch.</span>
2099+
<div><h2 id="profiling"><a href="#profiling" name="profiling">#</a>Profiling</h2><div><h3 id="stopwatch">Stopwatch</h3><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> perf_counter
2100+
start_time = perf_counter()
21012101
...
2102-
duration = time() - start_time
2102+
duration_in_seconds = perf_counter() - start_time
21032103
</code></pre></div></div>
21042104

21052105

2106-
<div><h4 id="highperformance">High performance:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> perf_counter
2107-
start_time = perf_counter() <span class="hljs-comment"># Seconds since the restart.</span>
2108-
...
2109-
duration = perf_counter() - start_time
2110-
</code></pre></div>
2111-
21122106
<div><h3 id="timingasnippet">Timing a Snippet</h3><pre><code class="python language-python hljs"><span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> timeit <span class="hljs-keyword">import</span> timeit
21132107
<span class="hljs-meta">&gt;&gt;&gt; </span>timeit(<span class="hljs-string">"''.join(str(i) for i in range(100))"</span>,
21142108
<span class="hljs-meta">... </span> number=<span class="hljs-number">10000</span>, globals=globals(), setup=<span class="hljs-string">'pass'</span>)
@@ -2139,8 +2133,9 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment
21392133
3 38.012 MiB 0.344 MiB a = [*range(10000)]
21402134
4 38.477 MiB 0.465 MiB b = {*range(10000)}
21412135
</code></pre>
2142-
<div><h3 id="callgraph">Call Graph</h3><div><h4 id="generatesapngimageofthecallgraphwithhighlightedbottlenecks">Generates a PNG image of the call graph with highlighted bottlenecks:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pycallgraph2; brew/apt install graphviz</span>
2136+
<div><h3 id="callgraph">Call Graph</h3><div><h4 id="generatesapngimageofthecallgraphwithhighlightedbottlenecks">Generates a PNG image of the call graph with highlighted bottlenecks:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install pycallgraph2; apt/brew install graphviz</span>
21432137
<span class="hljs-keyword">import</span> pycallgraph2 <span class="hljs-keyword">as</span> cg, datetime
2138+
21442139
filename = <span class="hljs-string">f'profile-<span class="hljs-subst">{datetime.datetime.now():%Y%m%d%H%M%S}</span>.png'</span>
21452140
drawer = cg.output.GraphvizOutput(output_file=filename)
21462141
<span class="hljs-keyword">with</span> cg.PyCallGraph(drawer):
@@ -2153,45 +2148,55 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment
21532148
</code></pre></div>
21542149

21552150

2156-
<pre><code class="python language-python hljs">&lt;array&gt; = np.array(&lt;list/list_of_lists&gt;)
2157-
&lt;array&gt; = np.arange(from_inclusive, to_exclusive, ±step_size)
2158-
&lt;array&gt; = np.ones(&lt;shape&gt;)
2159-
&lt;array&gt; = np.random.randint(from_inclusive, to_exclusive, &lt;shape&gt;)
2151+
<pre><code class="python language-python hljs">&lt;array&gt; = np.array(&lt;list/list_of_lists&gt;) <span class="hljs-comment"># Returns 1d/2d NumPy array.</span>
2152+
&lt;array&gt; = np.zeros/ones(&lt;shape&gt;) <span class="hljs-comment"># Also np.full(&lt;shape&gt;, &lt;el&gt;).</span>
2153+
&lt;array&gt; = np.arange(from_inc, to_exc, ±step) <span class="hljs-comment"># Also np.linspace(start, stop, num).</span>
2154+
&lt;array&gt; = np.random.randint(from_inc, to_exc, &lt;shape&gt;) <span class="hljs-comment"># Also np.random.random(&lt;shape&gt;).</span>
21602155
</code></pre>
2161-
<pre><code class="python language-python hljs">&lt;array&gt;.shape = &lt;shape&gt;
2162-
&lt;view&gt; = &lt;array&gt;.reshape(&lt;shape&gt;)
2163-
&lt;view&gt; = np.broadcast_to(&lt;array&gt;, &lt;shape&gt;)
2156+
<pre><code class="python language-python hljs">&lt;view&gt; = &lt;array&gt;.reshape(&lt;shape&gt;) <span class="hljs-comment"># Also `&lt;array&gt;.shape = &lt;shape&gt;`.</span>
2157+
&lt;array&gt; = &lt;array&gt;.flatten() <span class="hljs-comment"># Collapses array into one dimension.</span>
2158+
&lt;view&gt; = &lt;array&gt;.squeeze() <span class="hljs-comment"># Removes dimensions of length one.</span>
21642159
</code></pre>
2165-
<pre><code class="python language-python hljs">&lt;array&gt; = &lt;array&gt;.sum(axis)
2166-
indexes = &lt;array&gt;.argmin(axis)
2160+
<pre><code class="python language-python hljs">&lt;array&gt; = &lt;array&gt;.sum/min/mean/var/std(axis) <span class="hljs-comment"># Passed dimension gets aggregated.</span>
2161+
&lt;array&gt; = &lt;array&gt;.argmin(axis) <span class="hljs-comment"># Returns indexes of smallest elements.</span>
2162+
&lt;array&gt; = np.apply_along_axis(&lt;func&gt;, axis, &lt;array&gt;) <span class="hljs-comment"># Func can return a scalar or array.</span>
21672163
</code></pre>
21682164
<ul>
2169-
<li><strong>Shape is a tuple of dimension sizes.</strong></li>
2170-
<li><strong>Axis is an index of the dimension that gets aggregated. Leftmost dimension has index 0.</strong></li>
2165+
<li><strong>Shape is a tuple of dimension sizes. A 100x50 RGB image has shape (50, 100, 3).</strong></li>
2166+
<li><strong>Axis is an index of the dimension that gets aggregated. Leftmost/outermost dimension has index 0. Summing a 100x50 RGB image along the axis 2 will return a greyscale image with shape (50, 100).</strong></li>
2167+
<li><strong>Passing a tuple of axes will chain the operations like this: <code class="python hljs"><span class="hljs-string">'&lt;array&gt;.&lt;method&gt;(axis_1, keepdims=True).&lt;method&gt;(axis_2).squeeze()'</span></code>.</strong></li>
21712168
</ul>
2172-
<div><h3 id="indexing">Indexing</h3><pre><code class="bash language-bash hljs">&lt;el&gt; = &lt;2d_array&gt;[row_index, column_index]
2173-
&lt;1d_view&gt; = &lt;2d_array&gt;[row_index]
2174-
&lt;1d_view&gt; = &lt;2d_array&gt;[:, column_index]
2169+
<div><h3 id="indexing">Indexing</h3><pre><code class="bash language-bash hljs">&lt;el&gt; = &lt;2d_array&gt;[row_index, column_index] <span class="hljs-comment"># &lt;3d_a&gt;[table_i, row_i, column_i]</span>
2170+
&lt;1d_view&gt; = &lt;2d_array&gt;[row_index] <span class="hljs-comment"># &lt;3d_a&gt;[table_i, row_i]</span>
2171+
&lt;1d_view&gt; = &lt;2d_array&gt;[:, column_index] <span class="hljs-comment"># &lt;3d_a&gt;[table_i, :, column_i]</span>
21752172
</code></pre></div>
21762173

2177-
<pre><code class="bash language-bash hljs">&lt;1d_array&gt; = &lt;2d_array&gt;[row_indexes, column_indexes]
2178-
&lt;2d_array&gt; = &lt;2d_array&gt;[row_indexes]
2179-
&lt;2d_array&gt; = &lt;2d_array&gt;[:, column_indexes]
2174+
<pre><code class="bash language-bash hljs">&lt;1d_array&gt; = &lt;2d_array&gt;[row_indexes, column_indexes] <span class="hljs-comment"># &lt;3d_a&gt;[table_is, row_is, column_is]</span>
2175+
&lt;2d_array&gt; = &lt;2d_array&gt;[row_indexes] <span class="hljs-comment"># &lt;3d_a&gt;[table_is, row_is]</span>
2176+
&lt;2d_array&gt; = &lt;2d_array&gt;[:, column_indexes] <span class="hljs-comment"># &lt;3d_a&gt;[table_is, :, column_is]</span>
21802177
</code></pre>
2181-
<pre><code class="bash language-bash hljs">&lt;2d_bools&gt; = &lt;2d_array&gt; &gt;&lt;== &lt;el&gt;
2182-
&lt;1d_array&gt; = &lt;2d_array&gt;[&lt;2d_bools&gt;]
2178+
<pre><code class="bash language-bash hljs">&lt;2d_bools&gt; = &lt;2d_array&gt; &gt;&lt;== &lt;el&gt; <span class="hljs-comment"># &lt;3d_array&gt; &gt;&lt;== &lt;1d_array&gt;</span>
2179+
&lt;1d_array&gt; = &lt;2d_array&gt;[&lt;2d_bools&gt;] <span class="hljs-comment"># &lt;3d_array&gt;[&lt;2d_bools&gt;]</span>
21832180
</code></pre>
2184-
<div><h3 id="broadcasting">Broadcasting</h3><p><strong>Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.</strong></p><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
2185-
right = [ <span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span> ] <span class="hljs-comment"># Shape: (3)</span>
2181+
<ul>
2182+
<li><strong>All examples also allow assignments.</strong></li>
2183+
</ul>
2184+
<div><h3 id="broadcasting">Broadcasting</h3><p><strong>Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.</strong></p><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
2185+
right = [ <span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span> ] <span class="hljs-comment"># Shape: (3,)</span>
21862186
</code></pre></div>
21872187

21882188

2189-
<div><h4 id="1ifarrayshapesdifferinlengthleftpadtheshortershapewithones">1. If array shapes differ in length, left-pad the shorter shape with ones:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
2190-
right = [[<span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (1, 3) &lt;- !</span>
2189+
<div><h4 id="1ifarrayshapesdifferinlengthleftpadtheshortershapewithones">1. If array shapes differ in length, left-pad the shorter shape with ones:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 1)</span>
2190+
right = [[<span class="hljs-number">0.1</span> , <span class="hljs-number">0.6</span> , <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (1, 3) &lt;- !</span>
21912191
</code></pre></div>
21922192

2193-
<div><h4 id="2ifanydimensionsdifferinsizeexpandtheonesthathavesize1byduplicatingtheirelements">2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>], [<span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>], [<span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 3) &lt;- !</span>
2194-
right = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>], [<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>], [<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>]] <span class="hljs-comment"># Shape: (3, 3) &lt;- !</span>
2193+
<div><h4 id="2ifanydimensionsdifferinsizeexpandtheonesthathavesize1byduplicatingtheirelements">2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:</h4><pre><code class="python language-python hljs">left = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">0.1</span>], <span class="hljs-comment"># Shape: (3, 3) &lt;- !</span>
2194+
[<span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.6</span>],
2195+
[<span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>, <span class="hljs-number">0.8</span>]]
2196+
2197+
right = [[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>], <span class="hljs-comment"># Shape: (3, 3) &lt;- !</span>
2198+
[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>],
2199+
[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>]]
21952200
</code></pre></div>
21962201

21972202
<div><h4 id="3ifneithernonmatchingdimensionhassize1raiseanerror">3. If neither non-matching dimension has size 1, raise an error.</h4><div><h3 id="example-1">Example</h3><div><h4 id="foreachpointreturnsindexofitsnearestpoint010608121">For each point returns index of its nearest point (<code class="python hljs">[<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>] =&gt; [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>]</code>):</h4><pre><code class="python language-python hljs"><span class="hljs-meta">&gt;&gt;&gt; </span>points = np.array([<span class="hljs-number">0.1</span>, <span class="hljs-number">0.6</span>, <span class="hljs-number">0.8</span>])
@@ -2900,7 +2905,7 @@ <h3 id="format-2">Format</h3><div><h4 id="forstandardtypesizesandmanualalignment
29002905

29012906

29022907
<footer>
2903-
<aside>July 18, 2022</aside>
2908+
<aside>July 20, 2022</aside>
29042909
<a href="https://gto76.github.io" rel="author">Jure Šorn</a>
29052910
</footer>
29062911

0 commit comments

Comments
 (0)