import numpy as np
Let's look at how to extract pieces from an array or modify only some of its parts. For this, we have two tools:
- the extraction according to the indices
- the extraction by applying a logical filter on the values
Filter by indices¶
We can extract values from an array according to its indices as we did for lists. For each dimension of the table, you can indicate
- the value of the desired index (an integer)
- a list of
start:end:jump
indices. Thus1:6:2
means the odd values between index 1 and index 6 excluded. Thestart
,end
andjump
values are optional::5
gives the first 5 values (indices 0,1,2,3 and 4)3:
gives 4th to last values::3
returns a value every 3 from the beginning to the end of the array.
- an explicit list of indices like
[1,3,-2]
(negative values means start from the end, hence-2
is the penultimate index)
a = np.arange(12).reshape(3,4)
print(a, '\n')
print(a[1, :], '\n') # 2nd line
print(a[0:2, 0:2], '\n') # top left sub-matrix
print(a[::2, -1], '\n') # even lines, last column
print(a[:, [0,-1]]) # first and last column
[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [4 5 6 7] [[0 1] [4 5]] [ 3 11] [[ 0 3] [ 4 7] [ 8 11]]
It is thus possible to indicate that an operation only applies to an extract from the table by indicating which cells of the table will be modified:
a[::2, 1::2] += 100
a
array([[ 0, 101, 2, 103], [ 4, 5, 6, 7], [ 8, 109, 10, 111]])
It also makes it possible to simply write calculations such as extracting a grayscale image from a color image:
image = np.random.randint(256, size=(800, 600, 3)) # RGB 800x600 image
gray_image = 0.2126 * image[:,:,0] + 0.7152 * image[:,:,1] + 0.0722 * image[:,:,2]
You can also use ...
to replace multiple indices like image[...,0] == image[:,:,0]
Logical filters¶
A filter = a logical condition¶
Numpy allows you to simply extract the values that meet a logical condition.
To do this, we use a filter, namely a Boolean array that is placed on an array of the same size, imagining that the True boxes are windows and False are walls. The result is the set of values seen through the windows ordered by their index.
The result is always a 1-dimensional array unless you use where
.
a = np.arange(12).reshape(3,4)
fil = a > 5 # a > 5 means all VALUES greater than 5
print("The filter a > 5 is\n", fil)
a[fil] # apply the filter and show the result (1D array)
The filter a > 5 is [[False False False False] [False False True True] [ True True True True]]
array([ 6, 7, 8, 9, 10, 11])
It is easier and more readable to write the logical condition where we normally put the indices, namely between the square brackets:
a[a>5]
array([ 6, 7, 8, 9, 10, 11])
When the goal is the filter¶
The filter can be used for something other than selecting values from our array. It can be the result on which we want to work, for example for a population fil = (age == weight)
. It is an array of Boolean which gives true cases and other false cases i.e. 0s and 1s.
Thus, with a fil
filter, we can know
| | | |
|:-|:-|:-|
| how many cases are true: |fil.sum()
| |
| if there is at least one true case: |fil.sum() > 0
| Numpy also offers np.any(fil)
|
| if all cases are true: |fil.prod() == 1
| Numpy also offers np.all(fil)
|
| if at least one case is false: |fil.prod() == 0
|
|if all cases are false:| fil.sum() == 0
|
np.where(a > 5, a, 0) # if a > 5 then a else 0
array([[ 0, 0, 0, 0], [ 0, 0, 6, 7], [ 8, 9, 10, 11]])
We can make all imaginable filters that give a boolean array.
np.where(a%3 == 0, 2*a, -1) # if a modulo 3 is 0 then 2 times a else -1
array([[ 0, -1, -1, 6], [-1, -1, 12, -1], [-1, 18, -1, -1]])
Update a table with a filter¶
Another way to maintain the shape of the array is to change only the values that match the filter.
a = np.arange(12).reshape(3,4)
a[a > 5] = 200
a
array([[ 0, 1, 2, 3], [ 4, 5, 200, 200], [200, 200, 200, 200]])
Here's how to add 100 to all values in the array that are perfect squares as well as to the value 5:
a = np.arange(12).reshape(3,4)
a[(np.round(np.sqrt(a)) - np.sqrt(a) == 0) | (a==5)] += 100 # | is OR (AND is &)
a
array([[100, 101, 2, 3], [104, 105, 6, 7], [ 8, 109, 10, 11]])
{{ PreviousNext("np01 Numpy Introduction.ipynb", "np03 Manipulations.ipynb")}}