Skip to content

Commit fe1949a

Browse files
authored
Merge branch 'master' into sofia/boolean_indexing
2 parents 0fb2c71 + 4eb21b7 commit fe1949a

File tree

13 files changed

+285
-1
lines changed

13 files changed

+285
-1
lines changed

Numpy/Array Indexing and Slicing/Indexing Basics/__init__.py

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
type: edu
2+
files:
3+
- name: task.py
4+
visible: true
5+
placeholders:
6+
- offset: 240
7+
length: 7
8+
placeholder_text: '# TODO'
9+
- offset: 252
10+
length: 11
11+
placeholder_text: '# TODO'
12+
- name: tests/test_task.py
13+
visible: false
14+
- name: __init__.py
15+
visible: false
16+
- name: tests/__init__.py
17+
visible: false
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## Indexing Basics
2+
3+
Array indexing refers to any use of the square brackets (`[]`) to index array values.
4+
5+
### Single element indexing
6+
7+
Single element indexing for a 1-D array works exactly like that
8+
for other standard Python sequences. It is 0-based, and accepts negative indices for
9+
indexing from the end of the array.
10+
11+
Unlike lists and tuples, NumPy arrays support multidimensional indexing for multidimensional
12+
arrays. That means that **it is not necessary to separate each dimension’s index into its
13+
own set of square brackets**.
14+
15+
```python
16+
x = np.arange(10).reshape(2, 5) # 2-dimensional
17+
print(x[1, 3])
18+
print(x[1, -1])
19+
print(x[0])
20+
```
21+
Output:
22+
```text
23+
8
24+
9
25+
[0, 1, 2, 3, 4]
26+
```
27+
Note that `x[0, 2]` and `x[0][2]` will produce the same result, `2`. However, the second case
28+
is less efficient as a new temporary array is created after the first index that is subsequently
29+
indexed by 2.
30+
31+
### Slicing
32+
33+
It is possible to slice arrays to extract arrays of the same number of dimensions,
34+
but of different sizes than the original. The slicing works exactly the same way it
35+
does for lists and tuples except that they can be applied to multiple dimensions as well.
36+
Basic slicing occurs when obj is a slice object (constructed by `start:stop:step` notation inside
37+
of brackets), an integer, or a tuple of slice objects and integers.
38+
39+
1-D array:
40+
```python
41+
x = np.arange(35)
42+
print(x[2:15])
43+
print(x[1:30:5]) # [start:stop:step]
44+
```
45+
Output:
46+
```text
47+
[ 2 3 4 5 6 7 8 9 10 11 12 13 14]
48+
[ 1 6 11 16 21 26]
49+
```
50+
2-D array:
51+
```python
52+
y = x.reshape(5, 7)
53+
print(y[1:5:2])
54+
print(y[1:5:2, ::3]) # First slicing in the first dimension, then in the second.
55+
```
56+
Output:
57+
```text
58+
[[ 7 8 9 10 11 12 13]
59+
[21 22 23 24 25 26 27]]
60+
[[ 7 10 13]
61+
[21 24 27]]
62+
```
63+
64+
These examples show the use of indexing when referencing data in an array.
65+
They work just as well when assigning to an array.
66+
Read more about this topic [here](https://numpy.org/doc/stable/user/basics.indexing.html#basics-indexing).
67+
68+
### Task
69+
1. Variable `a`: use indexing on the array `x` to extract number `19` from it. Please
70+
**do not** just assign `a` the value `19` :)
71+
2. Variable `b`: use slicing to extract every second element in every second row. The resulting array
72+
should have shape `(5, 2)`.
73+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import numpy as np
2+
3+
x = np.arange(40).reshape(10, 4)
4+
# Array x:
5+
# [[ 0 1 2 3]
6+
# [ 4 5 6 7]
7+
# [ 8 9 10 11]
8+
# [12 13 14 15]
9+
# [16 17 18 19]
10+
# [20 21 22 23]
11+
# [24 25 26 27]
12+
# [28 29 30 31]
13+
# [32 33 34 35]
14+
# [36 37 38 39]]
15+
16+
a = x[4, 3]
17+
b = x[::2, ::2]
18+
19+
if __name__ == '__main__':
20+
print(a)
21+
print(b)

Numpy/Array Indexing and Slicing/Indexing Basics/tests/__init__.py

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import unittest
2+
import numpy as np
3+
4+
from task import a, b, x
5+
6+
7+
class TestCase(unittest.TestCase):
8+
def test_arrays_shape(self):
9+
self.assertEqual(b.shape, (5, 2), msg="Wrong shape of array b")
10+
self.assertEqual(type(a), np.int64, msg="a has to be a numpy.int64")
11+
12+
def test_array_content(self):
13+
self.assertEqual(a, 19, msg="a has to be equal to 19")
14+
np.testing.assert_array_equal(b, x[::2, ::2], err_msg='Something wrong in array b!')
15+

Numpy/Array Indexing and Slicing/Integer Array Indexing/__init__.py

Whitespace-only changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
type: edu
2+
files:
3+
- name: task.py
4+
visible: true
5+
placeholders:
6+
- offset: 63
7+
length: 28
8+
placeholder_text: '# TODO: use a 1-D numpy array for indexing'
9+
- offset: 96
10+
length: 52
11+
placeholder_text: '# TODO: use a 2-D numpy array for indexing'
12+
- offset: 155
13+
length: 22
14+
placeholder_text: '# TODO: use a 1-D numpy array for indexing'
15+
- offset: 182
16+
length: 43
17+
placeholder_text: '# TODO: use two 1-D arrays for indexing'
18+
- offset: 230
19+
length: 25
20+
placeholder_text: '# TODO: use a 1-D numpy array and a scalar for indexing'
21+
- name: tests/test_task.py
22+
visible: false
23+
- name: __init__.py
24+
visible: false
25+
- name: tests/__init__.py
26+
visible: false
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
## Integer array indexing
2+
3+
NumPy arrays may be indexed with other arrays.
4+
For all cases of index arrays, what is returned is a copy of the original data, not a view as one gets for slices.
5+
6+
Index arrays must be of integer type. Each value in the array indicates which value in the array
7+
to use in place of the index. Negative values are permitted and work as they do with single indices or slices.
8+
9+
```python
10+
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
11+
a = np.array([0, 3, 5, 2])
12+
print(x[a])
13+
```
14+
Output:
15+
```text
16+
[1 4 6 3]
17+
```
18+
19+
When index arrays are used, what is returned is an array with the same shape as the index
20+
array, but with the type and values of the array being indexed:
21+
```python
22+
b = np.array([[9, 9], [0, 1]])
23+
c = x[b]
24+
print(c)
25+
```
26+
Output:
27+
```text
28+
[[10 10]
29+
[ 1 2]]
30+
```
31+
32+
### Indexing multidimensional arrays
33+
Things become more complex when multidimensional arrays are indexed, particularly with multidimensional index arrays.
34+
Let's consider this:
35+
36+
```python
37+
x = np.arange(15).reshape(5, 3)
38+
print(x)
39+
print(x[np.array([0, 1, 4])]) # 1
40+
print(x[np.array([0, 1, 4]), np.array([0, 0, 1])]) # 2
41+
```
42+
Output:
43+
```text
44+
[[ 0 1 2]
45+
[ 3 4 5]
46+
[ 6 7 8]
47+
[ 9 10 11]
48+
[12 13 14]]
49+
50+
[[ 0 1 2]
51+
[ 3 4 5]
52+
[12 13 14]]
53+
54+
[ 0 3 13]
55+
```
56+
You can see that in the first case, a new array is constructed where
57+
each value of the index array selects one row from the indexed array and the resulting
58+
array has the shape `(number_of_index_elements, size_of_row)`.
59+
60+
In the second case, the resulting array has the same shape as the index arrays, and the values
61+
correspond to the index set for each position in the index arrays. In this example, the first
62+
index value is `0` for both index arrays, and thus the first value of the resulting array is `x[0, 0]`.
63+
The next value is `y[1, 0]`, and the last is `y[4, 1]`.
64+
65+
If the index arrays do not have the same shape, there is an attempt to broadcast them to the same shape.
66+
If they cannot be broadcast to the same shape, an exception is raised.
67+
68+
The broadcasting mechanism permits index arrays to be combined with scalars for other indices.
69+
The scalar value is used for all the corresponding values of the index arrays:
70+
71+
```python
72+
print(x[np.array([0, 2, 3, 4]), 1])
73+
```
74+
Output:
75+
```text
76+
[ 1 7 10 13]
77+
```
78+
You can read more about integer indexing [here](https://numpy.org/doc/stable/reference/arrays.indexing.html#integer-array-indexing).
79+
80+
### Task
81+
1. Using integer array indexing create an array `a` that contains elements with
82+
indices `[7, 13, 28, 33]` from the array `x`.
83+
Then create a 2-D array `b` with shape `(3, 3)` that contains elements with indices
84+
`[0, 1, 2], [10, 11, 12], [28, 29, 30]` from the array `x`.
85+
86+
2. Based on the 2-D array `y`:
87+
- Create an array `c` containing rows number `0`, `2` and `4`.
88+
- Create a 1-D array `d`, containing elements `0`, `1` and `2` from the rows `0`, `2` and `4`, respectively.
89+
- Create a 1-D array `e`, containing elements with index `6` from rows `1`, `2` and `4`.
90+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import numpy as np
2+
3+
x = np.arange(35)
4+
y = x.reshape(5, 7)
5+
6+
a = x[np.array([7, 13, 28, 33])]
7+
b = x[np.array([[0, 1, 2], [10, 11, 12], [28, 29, 30]])]
8+
9+
10+
c = y[np.array([0, 2, 4])]
11+
d = y[np.array([0, 2, 4]), np.array([0, 1, 2])]
12+
e = y[np.array([1, 2, 4]), 6]
13+
14+
15+
if __name__ == '__main__':
16+
print(y)
17+
print('\n', a.shape)
18+
print('\n', b.shape)
19+
print('\n', c.shape)
20+
print('\n', d.shape)
21+
print('\n', e.shape)

0 commit comments

Comments
 (0)