-
Notifications
You must be signed in to change notification settings - Fork 4
/
02-indexing.html
216 lines (215 loc) · 9.97 KB
/
02-indexing.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Software Carpentry: Advanced NumPy</title>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-theme.css" />
<link rel="stylesheet" type="text/css" href="css/swc.css" />
<link rel="alternate" type="application/rss+xml" title="Software Carpentry Blog" href="http://software-carpentry.org/feed.xml"/>
<meta charset="UTF-8" />
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body class="lesson">
<div class="container card">
<div class="banner">
<a href="http://software-carpentry.org" title="Software Carpentry">
<img alt="Software Carpentry banner" src="img/software-carpentry-banner.png" />
</a>
</div>
<article>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<a href="index.html"><h1 class="title">Advanced NumPy</h1></a>
<h2 class="subtitle">Indexing</h2>
<section class="objectives panel panel-warning">
<div class="panel-heading">
<h2 id="learning-objectives"><span class="glyphicon glyphicon-certificate"></span>Learning Objectives</h2>
</div>
<div class="panel-body">
<p>After the lesson learner:</p>
<ul>
<li>Can get the value of any element of a N-dimensional array knowing its row, column etc.</li>
<li>Can use slices to get and modify ranges of elements.</li>
<li>Can explain the difference between a copy and a view. Knows which methods of indexing return a copy or view.</li>
<li>Knows how to select elements from an array based on some criteria applied to their values.</li>
<li>Can obtain a sub-array of non-contiguous of elements using fancy indexing.</li>
</ul>
</div>
</section>
<h3 id="integer-indexing-and-slicing">Integer indexing and slicing</h3>
<p>Individual items of an array can be accessed by the integer index of the element (starting with 0):</p>
<pre><code>>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.array([a[0], a[2], a[-1]])
array([0, 2, 9])</code></pre>
<p>For two- or more dimensional arrays multiple indices should be specified:</p>
<pre><code>>>> b = np.arange(6).reshape(2,3)
>>> b
array([[0, 1, 2],
[3, 4, 5]])
>>> b[1, 2]
5</code></pre>
<p>Slicing allows to extract sub-arrays of multiple elements from an array. It’s defined by three integers separated by a colon, i.e. <code>start:end:increment</code>. Any of the integers can be skipped in which case they are replaced by defaults (0 for <code>start</code>, end of array for <code>end</code> and 1 for <code>increment</code>):</p>
<pre><code>>>> c = np.arange(9)
>>> c[1:3]
array([1, 2])
>>> c[:3]
array([0, 1, 2])
>>> c[1:]
array([1, 2, 3, 4, 5, 6, 7, 8])</code></pre>
<p>You can also assign elements with slices and indexes:</p>
<pre><code>>>> c
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> c[1:8:2]=1000
>>> c
array([ 0, 1000, 2, 1000, 4, 1000, 6, 1000, 8])</code></pre>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="view-or-copy"><span class="glyphicon glyphicon-pencil"></span>View or copy</h2>
</div>
<div class="panel-body">
<p>Create a 3x4 array of values from 0 to 11. Create another array as follows: <code>y = x[2]</code>. What happens when you modify <code>y</code> — does <code>x</code> also change? Now try <code>y = x[:2]</code> and modify it’s first element. What happens now?</p>
</div>
</section>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="checkerboard"><span class="glyphicon glyphicon-pencil"></span>Checkerboard</h2>
</div>
<div class="panel-body">
<p>Create an array of zeros and fill it with a checkerboard pattern with of size 8x8.</p>
<div class="figure">
<img src="fig/checkerboard.svg" />
</div>
</div>
</section>
<h3 id="boolean-mask">Boolean mask</h3>
<p>Sometimes we may want to select array elements based on their values. For this case boolean mask is very useful. The mask is an array of the same length as the indexed array containg only <code>False</code> or <code>True</code> values:</p>
<pre><code>>>> a = np.arange(4)
>>> a
array([0, 1, 2, 3])
>>> mask = np.array([False, True, True, False])
>>> a[mask]
array([1, 2])</code></pre>
<p>In most cases the mask is constructed from the values of the array itself. For example, to select only odd numbers we could use the following mask:</p>
<pre><code>>>> odd = (a % 2) == 1
>>> odd
array([False, True, False, True], dtype=bool)
>>> a[odd]
array([1, 3])</code></pre>
<p>This could be also done in a single step:</p>
<pre><code>>>> a[(a % 2) == 1]
array([1, 3])</code></pre>
<p>Indexing with a mask can be also useful to assign a new value to a sub-array:</p>
<pre><code>>>> a[(a % 2) == 1] = -1
>>> a
array([ 0, -1, 2, -1])</code></pre>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="view-or-copy-1"><span class="glyphicon glyphicon-pencil"></span>View or copy?</h2>
</div>
<div class="panel-body">
<p>What are the final values of <code>a</code> and <code>b</code> at the end of the following program? Explain why.</p>
<pre><code>a = np.arange(5)
b = a[a < 3]
b[::2] = 0</code></pre>
<ol style="list-style-type: lower-alpha">
<li><code>a = [0, 1, 2, 3, 4], b = [0, 1, 2]</code></li>
<li><code>a = [0, 1, 0, 3, 4], b = [0, 1, 0]</code></li>
<li><code>a = [0, 0, 2, 3, 4], b = [0, 0, 2]</code></li>
<li><code>a = [0, 1, 2, 3, 4], b = [0, 1, 0]</code></li>
<li><code>a = [0, 1, 2, 3, 4], b = [0, 1, 0, 3, 0]</code></li>
</ol>
</div>
</section>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="rectification"><span class="glyphicon glyphicon-pencil"></span>Rectification</h2>
</div>
<div class="panel-body">
<p>Rectify an array (replace negative elements with zeros) of random numbers from normal distribution (generated with <code>np.random.randn</code>) using boolean indexing.</p>
</div>
</section>
<h3 id="fancy-indexing">Fancy indexing</h3>
<p>Indexing can be done with an array of integers. In this case the same index can be also repeated several times:</p>
<pre><code>>>> a = np.arange(0, 100, 10)
>>> a
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
>>> a[[2, 3, 2, 4, 2]]
array([20, 30, 20, 40, 20])</code></pre>
<p>New values can be also assigned with this kind of indexing:</p>
<pre><code>>>> a[[9, 7]] = -100
>>> a
array([ 0, 10, 20, 30, 40, 50, 60, -100, 80, -100])</code></pre>
<p>When a new array is created by indexing with an array of integers, the new array has the same shape than the array of integers. Note that fancing indexing returns a copy and not a view.</p>
<pre><code>>>> a = np.arange(10)
>>> idx = np.array([[3, 4], [9, 7]])
>>> idx.shape
(2, 2)
>>> a[idx]
array([[3, 4],
[9, 7]])</code></pre>
<p>Fancy indexing is often used to re-order or sort data. You can easily obtain the indices required to sort data using <code>np.argsort</code>:</p>
<pre><code>>>> a = np.random.randint(10, size=5)
>>> a
array([4, 0, 6, 1, 2])
>>> i = np.argsort(a)
>>> a[i]
array([0, 1, 2, 4, 6])</code></pre>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="sub-arrays"><span class="glyphicon glyphicon-pencil"></span>Sub-arrays</h2>
</div>
<div class="panel-body">
<p>Let <code>x = np.array([1, 5, 10])</code>.</p>
<p>Which of the following will show [1, 10]:</p>
<ol style="list-style-type: lower-alpha">
<li><p><code>x[::2]</code></p></li>
<li><p><code>x[[1, 3]]</code></p></li>
<li><p><code>x[[0, 2]]</code></p></li>
<li><p><code>x[0, 2]</code></p></li>
<li><p><code>x[[1, -1]]</code></p></li>
<li><p><code>x[[False, True, False]]</code></p></li>
</ol>
<p>For each statement predict whether it returns a copy or a view.</p>
</div>
</section>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="random-elements"><span class="glyphicon glyphicon-pencil"></span>Random elements</h2>
</div>
<div class="panel-body">
<p>Using fancy indexing select randomly with repetition 10 elements from a random array of 100 elements (<em>Hint</em>: you can use <code>np.random.randint(max_int, size=n)</code> to generate <code>n</code> random numbers from 0 to <code>max_int</code>)</p>
</div>
</section>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2 id="drawing-random-integers-without-repetition"><span class="glyphicon glyphicon-pencil"></span>Drawing random integers without repetition</h2>
</div>
<div class="panel-body">
<p>Generate a random sequence of 10 integers from 1 to 100 without repetition (<em>Hint</em>: you may want to use <code>np.random.rand</code> and <code>np.argsort</code>).</p>
</div>
</section>
</div>
</div>
</article>
<div class="footer">
<a class="label swc-blue-bg" href="http://software-carpentry.org">Software Carpentry</a>
<a class="label swc-blue-bg" href="https://github.com/paris-swc/advanced-numpy-lesson">Source</a>
<a class="label swc-blue-bg" href="mailto:[email protected]">Contact</a>
<a class="label swc-blue-bg" href="LICENSE.html">License</a>
</div>
</div>
<!-- Javascript placed at the end of the document so the pages load faster -->
<script src="http://software-carpentry.org/v5/js/jquery-1.9.1.min.js"></script>
<script src="css/bootstrap/bootstrap-js/bootstrap.js"></script>
<script src='https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>
</body>
</html>