# 5.6. Array Select

## 5.6.1. Unique

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 2, 3, 1],
...               [1, 4, 5, 6]])
>>>
>>> np.unique(a)
array([1, 2, 3, 4, 5, 6])
>>>
>>> np.unique(a, axis=0)
array([[1, 2, 3, 1],
[1, 4, 5, 6]])
>>>
>>> np.unique(a, axis=1)
array([[1, 1, 2, 3],
[1, 6, 4, 5]])


## 5.6.2. Diagonal

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 2],
...               [3, 4]])
>>>
>>> a.diagonal()
array([1, 4])

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 2, 3],
...               [4, 5, 6]])
>>>
>>> a.diagonal()
array([1, 5])

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 2, 3],
...               [4, 5, 6],
...               [7, 8, 9]])
>>>
>>> a.diagonal()
array([1, 5, 9])


## 5.6.3. Nonzero

• Each element of the tuple contains one of the indices for each nonzero value.

• Therefore, the length of each tuple element is the number of nonzeros in the array.

• The first element of the tuple is the first index for each of the nonzero values: ([0, 0, 1, 1]).

• The second element of the tuple is the second index for each of the nonzero values: ([0, 2, 0, 2]).

• Pairs are zipped (first and second tuple):

• 0, 0

• 0, 2

• 1, 0

• 1, 2

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 0, 2],
...               [3, 0, 4]])
>>>
>>> a.nonzero()
(array([0, 0, 1, 1]),
array([0, 2, 0, 2]))
>>>
>>> a[a.nonzero()]
array([1, 2, 3, 4])


## 5.6.4. Where

• where(boolarray)

• indexes of elements

>>> import numpy as np


Single argument:

>>> a = np.array([1, 2, 3, 4, 5, 6])
>>>
>>> np.where(a != 2)
(array([0, 2, 3, 4, 5]),)
>>>
>>> np.where(a % 2 == 0)
(array([1, 3, 5]),)
>>>
>>> np.where( (a>2) & (a<5) )
(array([2, 3]),)

>>> a = np.array([[1, 2, 3],
...               [4, 5, 6],
...               [7, 8, 9]])
>>>
>>> np.where(a % 2 == 0)
(array([0, 1, 1, 2]),
array([1, 0, 2, 1]))
>>>
>>> np.where( (a>2) & (a<5) )
(array([0, 1]),
array([2, 0]))


## 5.6.5. Multiple argument

• where(boolarray, truearray, falsearray):

>>> import numpy as np
>>>
>>>
>>> a = np.array([[1, 2, 3],
...               [4, 5, 6],
...               [7, 8, 9]])

>>> np.where(a < 5, 'small', 'large')
array([['small', 'small', 'small'],
['small', 'large', 'large'],
['large', 'large', 'large']], dtype='<U5')

>>> np.where(a % 2 == 0, 'even', 'odd')
array([['odd', 'even', 'odd'],
['even', 'odd', 'even'],
['odd', 'even', 'odd']], dtype='<U4')

>>> np.where(a % 2 == 0, np.nan, a)
array([[ 1., nan,  3.],
[nan,  5., nan],
[ 7., nan,  9.]])


## 5.6.6. Take

>>> import numpy as np

>>> a = np.array([1, 2, 3])
>>> at_index = np.array([0, 0, 1, 2, 2, 1])
>>>
>>> a.take(at_index)
array([1, 1, 2, 3, 3, 2])

>>> a = np.array([[1, 2, 3],
...               [4, 5, 6],
...               [7, 8, 9]])
>>>
>>> at_index = np.array([0, 0, 1])
>>>
>>> a.take(at_index, axis=0)
array([[1, 2, 3],
[1, 2, 3],
[4, 5, 6]])
>>>
>>> a.take(at_index, axis=1)
array([[1, 1, 2],
[4, 4, 5],
[7, 7, 8]])


## 5.6.7. Assignments

"""
* Assignment: Numpy Select Isin
* Complexity: easy
* Lines of code: 6 lines
* Time: 5 min

English:
1. Set random seed to 0
2. Generate a: np.ndarray of size 50x50
3. a must contains random integers from 0 to 1024 inclusive
4. Create result: np.ndarray with elements selected from a which are power of two
5. Sort result in descending order
6. Run doctests - all must succeed

Polish:
1. Ustaw ziarno losowości na 0
2. Wygeneruj a: np.ndarray rozmiaru 50x50
3. a musi zawierać losowe liczby całkowite z zakresu od 0 do 1024 włącznie
4. Stwórz result: np.ndarray z elementami wybranymi z a, które są potęgami dwójki
5. Posortuj result w kolejności malejącej
6. Uruchom doctesty - wszystkie muszą się powieść

Hints:
* np.isin(a, b)
* np.flip(a)

Tests:
>>> import sys; sys.tracebacklimit = 0

>>> assert result is not Ellipsis, \
'Assign result to variable: result'
>>> assert type(result) is np.ndarray, \
'Variable result has invalid type, expected: np.ndarray'

>>> result
array([1024, 1024, 1024, 1024, 1024, 1024,  512,  512,  512,  512,  256,
256,  256,  256,  256,  128,  128,  128,  128,  128,   64,   32,
32,   32,   32,   32,   16,   16,   16,   16,   16,   16,    8,
8,    4,    2,    2,    2,    2,    2])
"""

import numpy as np
np.random.seed(0)

result = ...