# Chapter 4 numpy's mathematical function, logical function + Exercises

The concepts of vectorization and broadcasting are the basis of numpy's internal implementation. With vectorization, you don't need to use explicit loops when writing code. These loops can not be omitted, but are implemented internally and replaced by other structures in the code. The application of vectorization makes the code more concise and readable. It can also be said that the code using vectorization method looks more "Python".

The Broadcasting mechanism describes how numpy handles arrays with different shapes during arithmetic operations, allowing smaller arrays to "broadcast" on larger arrays so that they have compatible shapes. Not all dimensions need to be compatible with each other to meet the requirements of Broadcasting mechanism, but they must meet certain conditions.

If the dimensions of the two arrays are compatible, that is, each dimension of the two arrays is the same length, or one of the arrays is one dimension, the broadcast mechanism is applicable. If these two conditions are not met, numpy will throw an exception saying that the two arrays are incompatible.

To sum up, there are three rules for broadcasting:

• If the dimension number dim of the two arrays is different, the shape of the small dimension array will be supplemented by 1 on the left.
• If the shape dimensions do not match, but one dimension is 1, the dimension with dimension 1 can be extended to match another array;
• If the shape dimensions do not match, but none of the dimensions is 1, the matching will cause an error;

Reference article: https://www.cnblogs.com/jiaxin359/p/9021726.html

[example] two dimensional array plus one-dimensional array

```import numpy as np

x = np.arange(4)# [0 1 2 3]
y = np.ones((3, 4))
# [[1. 1. 1. 1.]
#  [1. 1. 1. 1.]
#  [1. 1. 1. 1.]]
print(x.shape)  # (4,)
print(y.shape)  # (3, 4)
print((x + y).shape)  # (3, 4)
print(x + y)
# [[1. 2. 3. 4.]
#  [1. 2. 3. 4.]
#  [1. 2. 3. 4.]]
```

[example] both arrays need to be broadcast

```import numpy as np

x = np.arange(4).reshape(4, 1)
# [
#  
#  
#  ]

y = np.ones(5)
# [1. 1. 1. 1. 1.]

print(x.shape)  # (4, 1)
print(y.shape)  # (5,)

print((x + y).shape)  # (4, 5)
print(x + y)
# [[1. 1. 1. 1. 1.]
#  [2. 2. 2. 2. 2.]
#  [3. 3. 3. 3. 3.]
#  [4. 4. 4. 4. 4.]]

x = np.array([0.0, 10.0, 20.0, 30.0])
y = np.array([1.0, 2.0, 3.0])
z = x[:, np.newaxis] + y
print(z)
# [[ 1.  2.  3.]
#  [11. 12. 13.]
#  [21. 22. 23.]
#  [31. 32. 33.]]
```

[example] example of mismatch error reporting

```import numpy as np

x = np.arange(4)
# [0 1 2 3]
y = np.ones(5)
# [1. 1. 1. 1. 1.]
print(y)
print(x.shape)  # (4,)
print(y.shape)  # (5,)

print(x + y)
# ValueError: operands could not be broadcast together with shapes (4,) (5,)
```

# 2, Mathematical function

## 1. Arithmetic operation

### 1.6numpy.power

• numpy.subtract(x1, x2, *args, **kwargs) subtracts the parameters element by element.
• numpy.multiply(x1, x2, *args, **kwargs) multiplies the parameters element by element.
• numpy.divide(x1, x2, *args, **kwargs) returns the true division of input divided by elements.
• numpy.floor_divide(x1, x2, *args, **kwargs) returns the largest integer less than or equal to the division entered
• numpy.power(x1, x2, *args, **kwargs) the first array element is raised from the second array to a power in terms of elements.

The above functions are overloaded with operators in numpy, and the operators are element level. In other words, they are only used between elements in the same position, and the obtained operation results form a new array.

[example] pay attention to the broadcast rules of numpy.

```import numpy as np

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x + 1
print(y)
# [2 3 4 5 6 7 8 9]

y = x - 1
print(y)
print(np.subtract(x, 1))
# [0 1 2 3 4 5 6 7]

y = x * 2
print(y)
print(np.multiply(x, 2))
# [ 2  4  6  8 10 12 14 16]

y = x / 2
print(y)
print(np.divide(x, 2))
# [0.5 1.  1.5 2.  2.5 3.  3.5 4. ]

y = x // 2
print(y)
print(np.floor_divide(x, 2))
# [0 1 1 2 2 3 3 4]

y = x ** 2
print(y)
print(np.power(x, 2))
# [ 1  4  9 16 25 36 49 64]
```

[example] pay attention to the broadcast rules of numpy.

```import numpy as np

x = np.array([[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]])
y = x + 1
print(y)
# [[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]]

y = x - 1
print(y)
print(np.subtract(x, 1))
# [[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]]

y = x * 2
print(y)
print(np.multiply(x, 2))
# [[22 24 26 28 30]
#  [32 34 36 38 40]
#  [42 44 46 48 50]
#  [52 54 56 58 60]
#  [62 64 66 68 70]]

y = x / 2
print(y)
print(np.divide(x, 2))
# [[ 5.5  6.   6.5  7.   7.5]
#  [ 8.   8.5  9.   9.5 10. ]
#  [10.5 11.  11.5 12.  12.5]
#  [13.  13.5 14.  14.5 15. ]
#  [15.5 16.  16.5 17.  17.5]]

y = x // 2
print(y)
print(np.floor_divide(x, 2))
# [[ 5  6  6  7  7]
#  [ 8  8  9  9 10]
#  [10 11 11 12 12]
#  [13 13 14 14 15]
#  [15 16 16 17 17]]

y = x ** 2
print(y)
print(np.power(x, 2))
# [[ 121  144  169  196  225]
#  [ 256  289  324  361  400]
#  [ 441  484  529  576  625]
#  [ 676  729  784  841  900]
#  [ 961 1024 1089 1156 1225]]
```

[example] pay attention to the broadcast rules of numpy.

```import numpy as np

x = np.array([[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]])

y = np.arange(1, 6)
print(y)
# [1 2 3 4 5]

z = x + y
print(z)
# [[12 14 16 18 20]
#  [17 19 21 23 25]
#  [22 24 26 28 30]
#  [27 29 31 33 35]
#  [32 34 36 38 40]]

z = x - y
print(z)
print(np.subtract(x, y))
# [[10 10 10 10 10]
#  [15 15 15 15 15]
#  [20 20 20 20 20]
#  [25 25 25 25 25]
#  [30 30 30 30 30]]

z = x * y
print(z)
print(np.multiply(x, y))
# [[ 11  24  39  56  75]
#  [ 16  34  54  76 100]
#  [ 21  44  69  96 125]
#  [ 26  54  84 116 150]
#  [ 31  64  99 136 175]]

z = x / y
print(z)
print(np.divide(x, y))
# [[11.          6.          4.33333333  3.5         3.        ]
#  [16.          8.5         6.          4.75        4.        ]
#  [21.         11.          7.66666667  6.          5.        ]
#  [26.         13.5         9.33333333  7.25        6.        ]
#  [31.         16.         11.          8.5         7.        ]]

z = x // y
print(z)
print(np.floor_divide(x, y))
# [[11  6  4  3  3]
#  [16  8  6  4  4]
#  [21 11  7  6  5]
#  [26 13  9  7  6]
#  [31 16 11  8  7]]

z = x ** np.full([1, 5], 2)
print(z)
print(np.power(x, np.full([5, 5], 2)))
# [[ 121  144  169  196  225]
#  [ 256  289  324  361  400]
#  [ 441  484  529  576  625]
#  [ 676  729  784  841  900]
#  [ 961 1024 1089 1156 1225]]
```

[example]

```import numpy as np

x = np.array([[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]])

y = np.arange(1, 26).reshape([5, 5])
print(y)
# [[ 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]]

z = x + y
print(z)
# [[12 14 16 18 20]
#  [22 24 26 28 30]
#  [32 34 36 38 40]
#  [42 44 46 48 50]
#  [52 54 56 58 60]]

z = x - y
print(z)
print(np.subtract(x, y))
# [[10 10 10 10 10]
#  [10 10 10 10 10]
#  [10 10 10 10 10]
#  [10 10 10 10 10]
#  [10 10 10 10 10]]

z = x * y
print(z)
print(np.multiply(x, y))
# [[ 11  24  39  56  75]
#  [ 96 119 144 171 200]
#  [231 264 299 336 375]
#  [416 459 504 551 600]
#  [651 704 759 816 875]]

z = x / y
print(z)
print(np.divide(x, y))
# [[11.          6.          4.33333333  3.5         3.        ]
#  [ 2.66666667  2.42857143  2.25        2.11111111  2.        ]
#  [ 1.90909091  1.83333333  1.76923077  1.71428571  1.66666667]
#  [ 1.625       1.58823529  1.55555556  1.52631579  1.5       ]
#  [ 1.47619048  1.45454545  1.43478261  1.41666667  1.4       ]]

z = x // y
print(z)
print(np.floor_divide(x, y))
# [[11  6  4  3  3]
#  [ 2  2  2  2  2]
#  [ 1  1  1  1  1]
#  [ 1  1  1  1  1]
#  [ 1  1  1  1  1]]

z = x ** np.full([5, 5], 2)
print(z)
print(np.power(x, np.full([5, 5], 2)))
# [[ 121  144  169  196  225]
#  [ 256  289  324  361  400]
#  [ 441  484  529  576  625]
#  [ 676  729  784  841  900]
#  [ 961 1024 1089 1156 1225]]
```

### 1.8numpy.square

• numpy.sqrt(x, *args, **kwargs) Return the non-negative square-root of an array, element-wise.
• numpy.square(x, *args, **kwargs) Return the element-wise square of the input.

[example]

```import numpy as np

x = np.arange(1, 5)
print(x)  # [1 2 3 4]

y = np.sqrt(x)
print(y)
# [1.         1.41421356 1.73205081 2.        ]
print(np.power(x, 0.5))
# [1.         1.41421356 1.73205081 2.        ]

y = np.square(x)
print(y)
# [ 1  4  9 16]
print(np.power(x, 2))
# [ 1  4  9 16]
```

## 2. Trigonometric function

### 2.6numpy.arctan

• numpy.sin(x, *args, **kwargs) Trigonometric sine, element-wise.
• numpy.cos(x, *args, **kwargs) Cosine element-wise.
• numpy.tan(x, *args, **kwargs) Compute tangent element-wise.
• numpy.arcsin(x, *args, **kwargs) Inverse sine, element-wise.
• numpy.arccos(x, *args, **kwargs) Trigonometric inverse cosine, element-wise.
• numpy.arctan(x, *args, **kwargs) Trigonometric inverse tangent, element-wise.

universal function is usually called ufunc, which operates on each element in the array one by one. This shows that the general function processes each element of the input array separately, and the generated results form a new output array. The size of the output array is the same as that of the input array.

Many mathematical operations such as trigonometric function conform to the definition of general function, such as sqrt() function for calculating square root, log() function for taking logarithm and sin() function for finding sine value.

[example]

```import numpy as np

x = np.linspace(start=0, stop=np.pi / 2, num=10)
print(x)
# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463
#  1.04719755 1.22173048 1.3962634  1.57079633]

y = np.sin(x)
print(y)
# [0.         0.17364818 0.34202014 0.5        0.64278761 0.76604444
#  0.8660254  0.93969262 0.98480775 1.        ]

z = np.arcsin(y)
print(z)
# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463
#  1.04719755 1.22173048 1.3962634  1.57079633]

y = np.cos(x)
print(y)
# [1.00000000e+00 9.84807753e-01 9.39692621e-01 8.66025404e-01
#  7.66044443e-01 6.42787610e-01 5.00000000e-01 3.42020143e-01
#  1.73648178e-01 6.12323400e-17]

z = np.arccos(y)
print(z)
# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463
#  1.04719755 1.22173048 1.3962634  1.57079633]

y = np.tan(x)
print(y)
# [0.00000000e+00 1.76326981e-01 3.63970234e-01 5.77350269e-01
#  8.39099631e-01 1.19175359e+00 1.73205081e+00 2.74747742e+00
#  5.67128182e+00 1.63312394e+16]

z = np.arctan(y)
print(z)
# [0.         0.17453293 0.34906585 0.52359878 0.6981317  0.87266463
#  1.04719755 1.22173048 1.3962634  1.57079633]
```

## 3. Exponent and logarithm

### 3.5numpy.log10

• numpy.exp(x, *args, **kwargs) calculates the exponent of all elements in the input array.
• numpy.log(x, *args, **kwargs) natural logarithm, element by element.
• numpy.exp2(x, *args, **kwargs) Calculate 2**p for all p in the input array.
• numpy. Log2 (x, * args, * * kwargs) the base 2 logarithm of X.
• numpy.log10(x, *args, **kwargs) returns the base 10 logarithm of the input array in units of elements.

Therefore, the exponent (exp log) of [x] is the reciprocal of [log]. Natural logarithm is the logarithm with base e.

```import numpy as np

x = np.arange(1, 5)
print(x)
# [1 2 3 4]
y = np.exp(x)
print(y)
# [ 2.71828183  7.3890561  20.08553692 54.59815003]
z = np.log(y)
print(z)
# [1. 2. 3. 4.]
```

## 4. Addition function and multiplication function

### 4.1numpy.sum

• numpy.sum(a[, axis=None, dtype=None, out=None,...]) the sum of array elements on a given axis.

Through different axes, numpy will operate in different directions: if it is not set, it will operate on all elements; If axis=0, operate along the longitudinal axis; axis=1, operate along the horizontal axis. But this is just a simple binary array. What if it is multidimensional? It can be summarized as one sentence: if axis=i, numpy will operate in the direction of the change of the ith subscript.

### 4.2numpy.cumsum

• numpy.cumsum(a, axis=None, dtype=None, out=None) returns the cumulative sum of elements along a given axis.

An aggregate function is a function that operates on a set of values (such as an array) and returns a single value as the result. Therefore, the function of finding the sum of all elements of the array is the aggregate function. The ndarray class implements several of these functions.

[example] returns the sum of array elements on a given axis.

```import numpy as np

x = np.array([[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]])
y = np.sum(x) # All+
print(y)  # 575

y = np.sum(x, axis=0) # Along column+
print(y)  # [105 110 115 120 125]

y = np.sum(x, axis=1) # Along the line+
print(y)  # [ 65  90 115 140 165]
```

[example] returns the cumulative sum of array elements on a given axis.

```import numpy as np

x = np.array([[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]])
y = np.cumsum(x)
print(y)
# [ 11  23  36  50  65  81  98 116 135 155 176 198 221 245 270 296 323 351
#  380 410 441 473 506 540 575]

y = np.cumsum(x, axis=0)# Along column+
print(y)
# [[ 11  12  13  14  15]
#  [ 27  29  31  33  35]
#  [ 48  51  54  57  60]
#  [ 74  78  82  86  90]
#  [105 110 115 120 125]]

y = np.cumsum(x, axis=1)# Along the line+
print(y)
# [[ 11  23  36  50  65]
#  [ 16  33  51  70  90]
#  [ 21  43  66  90 115]
#  [ 26  53  81 110 140]
#  [ 31  63  96 130 165]]
```

### 4.3numpy.prod product

• numpy.prod(a[, axis=None, dtype=None, out=None,...]) returns the product of array elements on a given axis.

### 4.4numpy.cumprod multiplication

• numpy.cumprod(a, axis=None, dtype=None, out=None) returns the cumulative product of elements along a given axis.

[example] returns the product of array elements on a given axis.

```import numpy as np

x = np.array([[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]])
y = np.prod(x)
print(y)  # 788529152

y = np.prod(x, axis=0)
print(y)
# [2978976 3877632 4972968 6294624 7875000]

y = np.prod(x, axis=1)
print(y)
# [  360360  1860480  6375600 17100720 38955840]
```

[example] returns the cumulative multiplication of array elements on a given axis.

```import numpy as np

x = np.array([[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]])
y = np.cumprod(x)
print(y)
# [         11         132        1716       24024      360360     5765760
#     98017920  1764322560  -837609728   427674624   391232512    17180672
#    395155456   893796352   870072320  1147043840   905412608  -418250752
#    755630080  1194065920 -1638662144  -897581056   444596224 -2063597568
#    788529152]

y = np.cumprod(x, axis=0)
print(y)
# [[     11      12      13      14      15]
#  [    176     204     234     266     300]
#  [   3696    4488    5382    6384    7500]
#  [  96096  121176  150696  185136  225000]
#  [2978976 3877632 4972968 6294624 7875000]]

y = np.cumprod(x, axis=1)
print(y)
# [[      11      132     1716    24024   360360]
#  [      16      272     4896    93024  1860480]
#  [      21      462    10626   255024  6375600]
#  [      26      702    19656   570024 17100720]
#  [      31      992    32736  1113024 38955840]]
```

### 4.5numpy.diff difference

• numpy. Calculate the difference along the given (n-axis = u, nonpen = 1, n = \\\\\\\\\\
• a: Input matrix
• n: Optional, representing how many times to perform the difference
• axis: the default is the last one

The first difference is given by out[i] = a[i+1] - a[i] along the given axis, higher differences are calculated by using diff recursively.

[example] calculate the discrete difference of the nth dimension along the specified axis.

```import numpy as np

A = np.arange(2, 14).reshape((3, 4))
# [[ 2  3  4  5]
#  [ 6  7  8  9]
#  [10 11 12 13]]

A[1, 1] = 8
print(A)
# [[ 2  3  4  5]
#  [ 6  8  8  9]
#  [10 11 12 13]]
print(np.diff(A))
# [[1 1 1]
#  [2 0 1]
#  [1 1 1]]
print(np.diff(A, axis=0))
# [[4 5 4 4]
#  [4 3 4 4]]
```

## 5. Rounding

### 5.1numpy. Round round

• numpy.around(a, decimals=0, out=None) rounds the array to the given number of decimal places

[example]

```import numpy as np

x = np.random.rand(3, 3) * 10
print(x)
# [[6.59144457 3.78566113 8.15321227]
#  [1.68241475 3.78753332 7.68886328]
#  [2.84255822 9.58106727 7.86678037]]

y = np.around(x)
print(y)
# [[ 7.  4.  8.]
#  [ 2.  4.  8.]
#  [ 3. 10.  8.]]

y = np.around(x, decimals=2)
print(y)
# [[6.59 3.79 8.15]
#  [1.68 3.79 7.69]
#  [2.84 9.58 7.87]]
```

### 5.3numpy.floor lower limit

• numpy.ceil(x, *args, **kwargs) returns the upper limit of input in units of elements.
• numpy.floor(x, *args, **kwargs) returns the lower limit of the input in units of elements.

[example]

```import numpy as np

x = np.random.rand(3, 3) * 10
print(x)
# [[0.67847795 1.33073923 4.53920122]
#  [7.55724676 5.88854047 2.65502046]
#  [8.67640444 8.80110812 5.97528726]]

y = np.ceil(x)
print(y)
# [[1. 2. 5.]
#  [8. 6. 3.]
#  [9. 9. 6.]]

y = np.floor(x)
print(y)
# [[0. 1. 4.]
#  [7. 5. 2.]
#  [8. 8. 5.]]
```

## 6. Miscellaneous

### 6.1numpy.clip clipping

• numpy.clip(a, a_min, a_max, out=None, **kwargs): clip (limit) the values in the array.

For example, if you specify the interval [[0, 1] `, the value less than 0 will become 0 and the value greater than 1 will become 1.

[example] crop (limit) the values in the array.

```import numpy as np

x = np.array([[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]])
y = np.clip(x, a_min=20, a_max=30)
print(y)
# [[20 20 20 20 20]
#  [20 20 20 20 20]
#  [21 22 23 24 25]
#  [26 27 28 29 30]
#  [30 30 30 30 30]]
```

### 6.3numpy.abs

• numpy.absolute(x, *args, **kwargs) calculates absolute values by element.
• numpy. Abbreviation of ABS (x, * args, * * kwargs).

[example]

```import numpy as np

x = np.arange(-5, 5)
print(x)
# [-5 -4 -3 -2 -1  0  1  2  3  4]

y = np.abs(x)
print(y)
# [5 4 3 2 1 0 1 2 3 4]

y = np.absolute(x)
print(y)
# [5 4 3 2 1 0 1 2 3 4]
```

### 6.4numpy.sign returns an element by element indication of a numeric symbol

• numpy.sign(x, *args, **kwargs)

[example]

```x = np.arange(-5, 5)
print(x)
#[-5 -4 -3 -2 -1  0  1  2  3  4]
print(np.sign(x))
#[-1 -1 -1 -1 -1  0  1  1  1  1]
```

reference

• https://mp.weixin.qq.com/s/RWsGvvmw4ptf7d8zPIDEJw

# 2, Logic function

## 1. Truth value test

### 1.2numpy.any

• numpy.all(a, axis=None, out=None, keepdims=np._NoValue) tests whether all array elements along a given axis evaluate to True.
• numpy.any(a, axis=None, out=None, keepdims=np._NoValue) tests whether any array element along a given axis evaluates to True.

[example]

```import numpy as np

a = np.array([0, 4, 5])
b = np.copy(a)
print(np.all(a == b))  # True
print(np.any(a == b))  # True

b = 1
print(np.all(a == b))  # False
print(np.any(a == b))  # True

print(np.all([1.0, np.nan]))  # True
print(np.any([1.0, np.nan]))  # True

a = np.eye(3)
print(np.all(a, axis=0))  # [False False False]
print(np.any(a, axis=0))  # [ True  True  True]
```

## 2. Array contents

### 2.1numpy.isnan

• numpy.isnan(x, *args, **kwargs) tests NaN element by element, and then returns the result as a Boolean array.

[example]

```import numpy as np
a=np.array([1,2,np.nan])
print(np.isnan(a))
```
```[False False  True]
```

## 3. Logical operation

### 3.4numpy.logical_xor

• numpy.logical_not(x, *args, **kwargs) calculates the true value of non-x elements.
• numpy.logical_and(x1, x2, *args, **kwargs) calculates the true values of X1 and x2 by element.
• numpy.logical_or(x1, x2, *args, **kwargs) calculates the true value of X1 or x2 by element.
• numpy.logical_xor(x1, x2, *args, **kwargs) returns the Boolean value after the XOR logic of X1 and x2.

[example] calculate the true value of non-x elements.

```import numpy as np

print(np.logical_not(3))
# False
print(np.logical_not([True, False, 0, 1]))
# [False  True  True False]

x = np.arange(5)
print(np.logical_not(x < 3))
# [False False False  True  True]
```

[example] calculate the true value of x1 AND x2 elements.

```print(np.logical_and(True, False))
# False
print(np.logical_and([True, False], [True, False]))
# [ True False]
print(np.logical_and(x > 1, x < 4))
# [False False  True  True False]

```

[example] calculate the true value of x1 OR x2 element by element.

```print(np.logical_or(True, False))
# True
print(np.logical_or([True, False], [False, False]))
# [ True False]
print(np.logical_or(x < 1, x > 3))
# [ True False False False  True]
```

[example] calculate the true value of x1 XOR x2 by element.

```print(np.logical_xor(True, False))
# True
print(np.logical_xor([True, True, False, False], [True, False, True, False]))
# [False  True  True False]
print(np.logical_xor(x < 1, x > 3))
# [ True False False False  True]
print(np.logical_xor(0, np.eye(2)))
# [[ True False]
#  [False  True]]
```

## 4. Control

### 4.6numpy.less_equal

• numpy.greater(x1, x2, *args, **kwargs) returns the true value of (x1 > x2) element by element.
• numpy.greater_equal(x1, x2, *args, **kwargs) returns the true value of (x1 > = x2) element by element.
• numpy.equal(x1, x2, *args, **kwargs) returns by element (x1 == x2).
• numpy.not_equal(x1, x2, *args, **kwargs) returns by element (x1! = x2).
• numpy.less(x1, x2, *args, **kwargs) returns the true value of (x1 < x2) by element.
• numpy.less_equal(x1, x2, *args, **kwargs) returns the true value of (x1 = < x2) element by element.

[example] numpy overloaded the operators of the above comparison functions.

```import numpy as np

x = np.array([1, 2, 3, 4, 5, 6, 7, 8])

y = x > 2
print(y)
print(np.greater(x, 2))
# [False False  True  True  True  True  True  True]

y = x >= 2
print(y)
print(np.greater_equal(x, 2))
# [False  True  True  True  True  True  True  True]

y = x == 2
print(y)
print(np.equal(x, 2))
# [False  True False False False False False False]

y = x != 2
print(y)
print(np.not_equal(x, 2))
# [ True False  True  True  True  True  True  True]

y = x < 2
print(y)
print(np.less(x, 2))
# [ True False False False False False False False]

y = x <= 2
print(y)
print(np.less_equal(x, 2))
# [ True  True False False False False False False]
```

[example]

```import numpy as np

x = np.array([[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]])
y = x > 20
print(y)
print(np.greater(x, 20))
# [[False False False False False]
#  [False False False False False]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]

y = x >= 20
print(y)
print(np.greater_equal(x, 20))
# [[False False False False False]
#  [False False False False  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]

y = x == 20
print(y)
print(np.equal(x, 20))
# [[False False False False False]
#  [False False False False  True]
#  [False False False False False]
#  [False False False False False]
#  [False False False False False]]

y = x != 20
print(y)
print(np.not_equal(x, 20))
# [[ True  True  True  True  True]
#  [ True  True  True  True False]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]

y = x < 20
print(y)
print(np.less(x, 20))
# [[ True  True  True  True  True]
#  [ True  True  True  True False]
#  [False False False False False]
#  [False False False False False]
#  [False False False False False]]

y = x <= 20
print(y)
print(np.less_equal(x, 20))
# [[ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [False False False False False]
#  [False False False False False]
#  [False False False False False]]
```

[example]

```import numpy as np

np.random.seed(20200611)
x = np.array([[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]])

y = np.random.randint(10, 40, [5, 5])
print(y)
# [[32 28 31 33 37]
#  [23 37 37 30 29]
#  [32 24 10 33 15]
#  [27 17 10 36 16]
#  [25 32 23 39 34]]

z = x > y
print(z)
print(np.greater(x, y))
# [[False False False False False]
#  [False False False False False]
#  [False False  True False  True]
#  [False  True  True False  True]
#  [ True False  True False  True]]

z = x >= y
print(z)
print(np.greater_equal(x, y))
# [[False False False False False]
#  [False False False False False]
#  [False False  True False  True]
#  [False  True  True False  True]
#  [ True  True  True False  True]]

z = x == y
print(z)
print(np.equal(x, y))
# [[False False False False False]
#  [False False False False False]
#  [False False False False False]
#  [False False False False False]
#  [False  True False False False]]

z = x != y
print(z)
print(np.not_equal(x, y))
# [[ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True False  True  True  True]]

z = x < y
print(z)
print(np.less(x, y))
# [[ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True False  True False]
#  [ True False False  True False]
#  [False False False  True False]]

z = x <= y
print(z)
print(np.less_equal(x, y))
# [[ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True False  True False]
#  [ True False False  True False]
#  [False  True False  True False]]
```

[example] pay attention to the broadcast rules of numpy.

```import numpy as np

x = np.array([[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]])

np.random.seed(20200611)
y = np.random.randint(10, 50, 5)

print(y)
# [32 37 30 24 10]

z = x > y
print(z)
print(np.greater(x, y))
# [[False False False False  True]
#  [False False False False  True]
#  [False False False False  True]
#  [False False False  True  True]
#  [False False  True  True  True]]

z = x >= y
print(z)
print(np.greater_equal(x, y))
# [[False False False False  True]
#  [False False False False  True]
#  [False False False  True  True]
#  [False False False  True  True]
#  [False False  True  True  True]]

z = x == y
print(z)
print(np.equal(x, y))
# [[False False False False False]
#  [False False False False False]
#  [False False False  True False]
#  [False False False False False]
#  [False False False False False]]

z = x != y
print(z)
print(np.not_equal(x, y))
# [[ True  True  True  True  True]
#  [ True  True  True  True  True]
#  [ True  True  True False  True]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]

z = x < y
print(z)
print(np.less(x, y))
# [[ True  True  True  True False]
#  [ True  True  True  True False]
#  [ True  True  True False False]
#  [ True  True  True False False]
#  [ True  True False False False]]

z = x <= y
print(z)
print(np.less_equal(x, y))
# [[ True  True  True  True False]
#  [ True  True  True  True False]
#  [ True  True  True  True False]
#  [ True  True  True False False]
#  [ True  True False False False]]
```

### 4.7numpy.allclose

• numpy.isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False) returns a Boolean array where the two arrays are equal in elements within the tolerance range.
• numpy. If the two elements are in the range of True-all, A-close = 1, B = 5, then the tolerance is returned in the range of True-all, A-close = 1.

numpy.allclose() is equivalent to numpy all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan)).

The tolerance value is positive and usually small. Add the relative difference (rtol * abs (b)) and the absolute difference atol to compare with the absolute difference between a and B.

Calculation basis for judging whether it is True:

```np.absolute(a - b) <= (atol + rtol * absolute(b))

- atol: float，Absolute tolerance.
- rtol: float，Relative tolerance.
```

If NaN is in the same location and equal_nan = True, they are considered equal. If the inf s in two arrays are in the same position and have the same sign, they are considered equal.

[example] compare whether two arrays can be considered equal.

```import numpy as np

x = np.isclose([1e10, 1e-7], [1.00001e10, 1e-8])
print(x)  # [ True False]

x = np.allclose([1e10, 1e-7], [1.00001e10, 1e-8])
print(x)  # False

x = np.isclose([1e10, 1e-8], [1.00001e10, 1e-9])
print(x)  # [ True  True]

x = np.allclose([1e10, 1e-8], [1.00001e10, 1e-9])
print(x)  # True

x = np.isclose([1e10, 1e-8], [1.0001e10, 1e-9])
print(x)  # [False  True]

x = np.allclose([1e10, 1e-8], [1.0001e10, 1e-9])
print(x)  # False

x = np.isclose([1.0, np.nan], [1.0, np.nan])
print(x)  # [ True False]

x = np.allclose([1.0, np.nan], [1.0, np.nan])
print(x)  # False

x = np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
print(x)  # [ True  True]

x = np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
print(x)  # True
```

# 3, Exercises

## 1. Mathematical function

Replace the value greater than 30 in array a with 30 and the value less than 10 with 10.

• a = np.random.uniform(1, 50, 20)

[knowledge points: mathematical function, search]

• How do I replace all values greater than a given value with a given cutoff value?
```import numpy as np

np.set_printoptions(precision=2)
np.random.seed(100)
a = np.random.uniform(1, 50, 20)
print(a)
# [27.63 14.64 21.8  42.39  1.23  6.96 33.87 41.47  7.7  29.18 44.67 11.25
#  10.08  6.31 11.77 48.95 40.77  9.43 41.   14.43]

# Method 1
b = np.clip(a, a_min=10, a_max=30)
print(b)
# [27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
#  10.08 10.   11.77 30.   30.   10.   30.   14.43]

# Method 2
b = np.where(a < 10, 10, a)
b = np.where(b > 30, 30, b)
print(b)
# [27.63 14.64 21.8  30.   10.   10.   30.   30.   10.   29.18 30.   11.25
#  10.08 10.   11.77 30.   30.   10.   30.   14.43]
```

Find all peaks in a one-dimensional digital array a. The peak is a point surrounded by smaller values on both sides.

• a = np.array([1, 3, 7, 1, 2, 6, 0, 1])

[knowledge points: mathematical function, search]

• How to find all local maxima (or peaks) in a one-dimensional array?
```import numpy as np

a = np.array([1, 3, 7, 1, 2, 6, 0, 1])
b1 = np.diff(a)
b2 = np.sign(b1)
b3 = np.diff(b2)

print(b1)  # [ 2  4 -6  1  4 -6  1]
print(b2)  # [ 1  1 -1  1  1 -1  1]
print(b3)  # [ 0 -2  2  0 -2  2]
index = np.where(np.equal(b3, -2)) + 1
print(index) # [2 5]
```

For a given one-dimensional array, calculate the moving average of window size 3.

• z = np.random.randint(10, size=10)

[knowledge point: mathematical function]

• How to calculate the moving average of numpy array?
```import numpy as np

np.random.seed(100)
z = np.random.randint(10, size=10)
print(z)
# [8 8 3 7 7 0 4 2 5 2]

def MovingAverage(arr, n=3):
a = np.cumsum(arr)
a[n:] = a[n:] - a[:-n]
return a[n - 1:] / n

r = MovingAverage(z, 3)
print(np.around(r, 2))
# [6.33 6.   5.67 4.67 3.67 2.   3.67 3.  ]
```

Normalize a 5x5 random matrix

[knowledge point: mathematical function]

• (prompt: (x - min) / (max - min))
```Z = np.random.random((5,5))
Zmax, Zmin = Z.max(), Z.min()
Z = (Z - Zmin)/(Zmax - Zmin)
print(Z)
```

Five different methods are used to extract the integer part of a random array

[knowledge point: mathematical function]

• (prompt:%, np.floor, np.ceil, astype, np.trunc)
```Z = np.random.uniform(0,10,10)

print (Z - Z%1)
print (np.floor(Z))
print (np.ceil(Z)-1)
print (Z.astype(int))
print (np.trunc(Z))
```

Considering a set of dimensions Z, a two-dimensional array is constructed. Its first row (Z , Z , Z ) is shifted by 1 (the last row should be (Z [- 3], Z [-2], Z [-1])

[knowledge point: mathematical function]

• (prompt NP. Lib. Stripe_tricks)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ----- > [the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG oahsuhlx-1620374503354) (attachment: image. PNG)]

np.arange(10).itemsize

```from numpy.lib import stride_tricks
def rolling(a, window):
shape = (a.size - window + 1, window)
strides = (a.itemsize, a.itemsize)
return stride_tricks.as_strided(a, shape=shape, strides=strides)
Z = rolling(np.arange(10), 3)
print (Z)
```

Considering two sets of point sets P0 and P1 to describe a set of lines (two-dimensional) and a point p, how to calculate the distance from point p to each line i (P0[i],P1[i])?

[knowledge point: mathematical function]

• Prompt: if P(x0,y0) is set, the linear equation is: Ax+By+C=0
Then the distance from P to the straight line is: d=|Ax0+By0+C| / √ (A) ²+ B ²)
```import numpy as np
def distance(P0,P1,p):
A=-1/(P1[:,0]-P0[:,0])
B=1/(P1[:,1]-P0[:,1])
C=P0[:,0]/(P1[:,0]-P0[:,0])-P0[:,1]/(P1[:,1]-P0[:,1])
return np.abs(A*p[:,0]+B*p[:,1]+C)/np.sqrt(A**2+B**2)
```
```P0 = np.random.uniform(-10,10,(10,2))
P1 = np.random.uniform(-10,10,(10,2))
p  = np.random.uniform(-10,10,( 1,2))

print (distance(P0, P1, p))
```

Draw sine function and cosine function, x = NP arange(0, 3 * np.pi, 0.1)？

```import numpy as np
from matplotlib import pyplot as plt
x = np.arange(0, 3*np.pi, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1)
plt.plot(x, y2)
```

Subtract the average of each row of the matrix?

```X = np.random.rand(5, 10)
# new
Y = X - X.mean(axis=1, keepdims=True)
# used
Y = X - X.mean(axis=1).reshape(-1, 1)
print(Y)
```

Conduct probabilistic statistical analysis?

• arr1 = np.random.randint(1,10,10) arr2 = np.random.randint(1,10,10))
```f
arr1 = np.random.randint(1,10,10)
arr2 = np.random.randint(1,10,10)

print("arr1 The average is:%s" %np.mean(arr1))
print("arr1 The median is:%s" %np.median(arr1))
print("arr1 The variance of is:%s" %np.var(arr1))
print("arr1 The standard deviation of is:%s" %np.std(arr1))
print("arr1,arr The correlation matrix is:%s" %np.cov(arr1,arr2))
print("arr1,arr The covariance matrix is:%s" %np.corrcoef(arr1,arr2))
```

## 2. Logic function

Gets the location where the a and b elements match.

• a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
• b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])

[knowledge point: logic function]

• How to get the matching position of two array elements?
```import numpy as np

a = np.array([1, 2, 3, 2, 3, 4, 3, 4, 5, 6])
b = np.array([7, 2, 10, 2, 7, 4, 9, 4, 9, 8])

# Method 1
print(x)  # (array([1, 3, 5, 7], dtype=int64),)

# Method 2
print(x)  # (array([1, 3, 5, 7], dtype=int64),)
```

Get all elements between 5 and 10.

• a = np.array([2, 6, 1, 9, 10, 3, 27])

[knowledge point: logic function]

• How to extract all elements in a given range from numpy array?
```import numpy as np

a = np.array([2, 6, 1, 9, 10, 3, 27])
mask = np.logical_and(np.greater_equal(a, 5), np.less_equal(a, 10))

# Method 1
print(a[x])  # [ 6  9 10]

# Method 2
print(a[x])  # [ 6  9 10]

# Method 3
x = a[np.logical_and(a >= 5, a <= 10)]
print(x)  # [ 6  9 10]
```

For two random arrays A and B, check that they are equal

[knowledge point: logic function]

• (prompt: np.allclose, np.array_equal)
```A = np.random.randint(0,2,5)
B = np.random.randint(0,2,5)
```
```# Assuming identical shape of the arrays and a tolerance for the comparison of values
equal = np.allclose(A,B)
print(equal)
```

How to negate a Boolean value or change the sign of a floating-point number in place?

[knowledge point: logic function]

• (prompt: np.logical_not, np.negative)
```Z = np.array([0,1])
print(Z)
np.logical_not(Z, out=Z)
# Z = np.random.uniform(-1.0,1.0,100)

# np.negative(Z, out=Z)
```
```Z = np.array([0.2,1.15])
print(Z)
np.negative(Z, out=Z)
```

Find the closest value in the given array

```Z=np.array([[0,1,2,3],[4,5,6,7]])
print(Z)
z=5.1
np.abs(Z - z).argmin()
print(Z.flat[np.abs(Z - z).argmin()])
```

Keywords: Python numpy

Added by simonp on Thu, 17 Feb 2022 20:39:37 +0200