# Python Basics | Numpy Detailed Tutorial

⭐This column aims to explain the basic grammar of Python in detail, summarize the key points in the grammar, and explain the difficulties in detail. It is aimed at zero-based and entry-level learners. Through the study of the column, you can master python programming proficiently, and at the same time, it will be used for subsequent data analysis. Lay a solid foundation for coding capabilities in machine learning and deep learning.

🔥This article has been included in the Python Basics series column: Python Basic Series Tutorial Welcome to subscribe and keep updating.

## 10.1 Why use Numpy

### 10.1.1  Inefficient Python for loop

[Example] Find the reciprocal of a million numbers

```def compute_reciprocals(values):
res = []
for value in values:      # Each time an element is traversed, its type is determined and the correct function for that data type is found
res.append(1/value)
return res

values = list(range(1, 1000000))
%timeit compute_reciprocals(values)
```
```145 ms ± 13.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```

%timeit : Magic method for running time statistics in ipython (average of multiple runs)

```import numpy as np

values = np.arange(1, 1000000)
%timeit 1/values
```
```5.99 ms ± 33.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```

To achieve the same calculation, Numpy runs 25 times faster than Python loops, resulting in a qualitative leap

### 10.1.2  Why Numpy is so efficient

Numpy is written in C

1. Compiled language VS interpreted language

When the C language is executed, the code is compiled as a whole, which is faster

2. Continuous single type storage VS scattered variable type storage

(1) The data types in Numpy arrays must be uniform, such as all floating point types, while Python lists support filling of any type of data

(2) The data in the Numpy array is stored continuously in the memory, while the data in the Python list is scattered in the memory

This storage structure is more in line with some more efficient underlying processing methods

Python language has thread locks during execution, which cannot achieve true multi-threaded parallelism, while C language can

### 10.1.3   When to use Numpy

In the process of data processing, when using "Python for loop" to implement some vectorization and matrix operations, it is necessary to give priority to using Numpy

Such as: 1. Dot product of two vectors

2, matrix multiplication

## 10.2 Creation of Numpy arrays

### 10.2.1 Creating from a list

```import numpy as np

x = np.array([1, 2, 3, 4, 5])
print(x)
```
```[1 2 3 4 5]
```
```print(type(x))
print(x.shape)
```
```<class 'numpy.ndarray'>
(5,)
```
• Set the data type of the array
```x = np.array([1, 2, 3, 4, 5], dtype="float32")
print(x)
print(type(x[0]))
```
```[1. 2. 3. 4. 5.]
<class 'numpy.float32'>
```
• Two-dimensional array
```x = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(x)
print(x.shape)
```
```[[1 2 3]
[4 5 6]
[7 8 9]]
(3, 3)
```

### 10.2.2 Creating an array from scratch

(1) Create an array of length 5, all values ​​are 0

```np.zeros(5, dtype=int)
```
```array([0, 0, 0, 0, 0])
```

(2) Create a 2*4 floating-point array with values ​​1

```np.ones((2, 4), dtype=float)
```
```array([[1., 1., 1., 1.],
[1., 1., 1., 1.]])
```

(3) Create a 3*5 array with a value of 8.8

```np.full((3, 5), 8.8)
```
```array([[8.8, 8.8, 8.8, 8.8, 8.8],
[8.8, 8.8, 8.8, 8.8, 8.8],
[8.8, 8.8, 8.8, 8.8, 8.8]])
```

(4) Create a 3*3 identity matrix

```np.eye(3)
```
```array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
```

(5) Create a linear sequence array, starting from 1 and ending at 15, with a step size of 2

```np.arange(1, 15, 2)
```
```array([ 1,  3,  5,  7,  9, 11, 13])
```

(6) Create an array of 4 elements, and these four numbers are evenly distributed to 0~1

```np.linspace(0, 1, 4)
```
```array([0.        , 0.33333333, 0.66666667, 1.        ])
```

(7) Create an array of 10 elements to form a proportional sequence of 1~10^9

```np.logspace(0, 9, 10)
```
```array([1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, 1.e+07,
1.e+08, 1.e+09])
```

(8) Create a 3*3 array of random numbers uniformly distributed between 0 and 1

```np.random.random((3,3))
```
```array([[0.24347952, 0.41715541, 0.41363866],
[0.44869706, 0.18128167, 0.18568051],
[0.05705023, 0.0689205 , 0.74837661]])
```

(9) Create a 3*3 array of normally distributed random numbers with a mean of 0 and a standard deviation of 1

```np.random.normal(0, 1, (3,3))
```
```array([[-0.38530465,  0.17474932,  0.31129291],
[ 1.61626424, -2.18883854,  0.54043825],
[-0.9141666 , -0.03804043, -0.6645122 ]])
```

(10) Create a 3*3 array of random integers between [0,10)

```np.random.randint(0, 10, (3,3))
```
```array([[9, 1, 9],
[0, 3, 9],
[8, 5, 4]])
```

(11) Random rearrangement

```import numpy as np
x = np.array([10, 20, 30, 40])
np.random.permutation(x)       # Produce a new list without affecting the original list.
```
```array([30, 40, 20, 10])
```
```print(x)
np.random.shuffle(x)          # Modify the original list
print(x)
```
```[10 20 30 40]
[20 40 10 30]
```

(12) Random sampling

• Sample by the specified shape
```x = np.arange(10, 25, dtype = float)
x
```
```array([10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22.,
23., 24.])
```
```np.random.choice(x, size=(4, 3))
```
```array([[19., 23., 22.],
[22., 21., 13.],
[15., 21., 17.],
[14., 23., 19.]])
```
```import numpy as np
np.random.choice(10, 10)
```
```array([0, 0, 9, 5, 8, 5, 2, 4, 9, 8])
```
```x = np.arange(5).reshape(1, 5)
x
x.sum(axis=1, keepdims=True)
```
```array([[10]])
```
• Sampling with probability
```np.random.choice(x, size=(4, 3), p=x/np.sum(x))
```
```array([[15., 21., 20.],
[23., 17., 18.],
[23., 15., 17.],
[19., 24., 22.]])
```

## 10.3 Properties of Numpy Arrays

### 10.3.1 Properties of arrays

```x = np.random.randint(10, size=(3, 4))
x
```
```array([[5, 5, 2, 7],
[2, 3, 0, 8],
[3, 8, 1, 7]])
```

1. The shape of the array

```x.shape
```
```(3, 4)
```

2. The dimension ndim of the array

```x.ndim
```
```2
```
```y = np.arange(10)

```
```array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
```y.ndim
```
```1
```

3. The size of the array

```x.size
```
```12
```

4. The data type dtype of the array

```x.dtype
```
```dtype('int32')
```

### 10.3.2 Array Indexing

1. Index of a one-dimensional array

```x1 = np.arange(10)
x1
```
```array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
```x1[0]
```
```0
```
```x1[5]
```
```5
```
```x1[-1]
```
```9
```

2. Indexing of multidimensional arrays - take two dimensions as an example

```x2 = np.random.randint(0, 20, (2,3))
x2
```
```array([[11,  3, 11],
[ 6,  1,  5]])
```
```x2[0, 0]
```
```11
```
```x2[0][0]
```
```11
```

Note: The data type of numpy arrays is fixed. Insert a floating point value into an integer array, and the floating point value will be rounded down.

```x2[0, 0] = 1.618
```
```x2
```
```array([[ 1,  3, 11],
[ 6,  1,  5]])
```

### 10.3.3 Slicing of Arrays

1. One-dimensional arrays - just like lists

```x1 = np.arange(10)
x1
```
```array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
```x1[:3]
```
```array([0, 1, 2])
```
```x1[3:]
```
```array([3, 4, 5, 6, 7, 8, 9])
```
```x1[::-1]
```
```array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
```

2. Multidimensional arrays - take two dimensions as an example

```x2 = np.random.randint(20, size=(3,4))
x2
```
```array([[14,  9, 15,  8],
[18,  8, 16, 17],
[ 0,  8,  2, 17]])
```
```x2[:2, :3]             # First two rows, first three columns
```
```array([[14,  9, 15],
[18,  8, 16]])
```
```x2[:2, 0:3:2]       # First two rows First three columns (every other column)
```
```array([[14, 15],
[18, 16]])
```
```x2[::-1, ::-1]
```
```array([[17,  2,  8,  0],
[17, 16,  8, 18],
[ 8, 15,  9, 14]])
```

3. Get the rows and columns of an array

```x3 = np.random.randint(20, size=(3,4))
x3
```
```array([[ 8, 13, 15,  7],
[19, 13, 17,  6],
[11,  2,  0, 12]])
```
```x3[1, :]   #The first line counts from 0
```
```array([19, 13, 17,  6])
```
```x3[1]    # first line abbreviation
```
```array([19, 13, 17,  6])
```
```x3[:, 2]  # The second column counts from 0
```
```array([15, 17,  0])
```

4. Slices get views, not copies

```x4 = np.random.randint(20, size=(3,4))
x4
```
```array([[ 5, 14,  7,  2],
[ 8, 12,  9,  3],
[19,  0, 10,  7]])
```
```x5 = x4[:2, :2]
x5
```
```array([[ 5, 14],
[ 8, 12]])
```

Note: If the view element is modified, the original array will also be modified accordingly

```x5[0, 0] = 0
x5
```
```array([[ 0, 14],
[ 8, 12]])
```
```x4
```
```array([[ 0, 14,  7,  2],
[ 8, 12,  9,  3],
[19,  0, 10,  7]])
```

Safe way to modify slices: copy

```x4 = np.random.randint(20, size=(3,4))
x4
```
```array([[18, 14, 10, 12],
[10, 16,  7, 19],
[ 3, 16,  3, 12]])
```
```x6 = x4[:2, :2].copy()
x6
```
```array([[18, 14],
[10, 16]])
```
```x6[0, 0] = 0
x6
```
```array([[ 0, 14],
[10, 16]])
```
```x4
```
```array([[18, 14, 10, 12],
[10, 16,  7, 19],
[ 3, 16,  3, 12]])
```

### 10.3.4 Deformation of arrays

```x5 = np.random.randint(0, 10, (12,))
x5
```
```array([5, 0, 1, 3, 2, 6, 3, 8, 7, 5, 2, 5])
```
```x5.shape
```
```(12,)
```
```x6 = x5.reshape(3, 4)
x6
```
```array([[9, 8, 5, 9],
[2, 6, 2, 9],
[4, 5, 1, 7]])
```

Note: reshape returns a view, not a copy

```x6[0, 0] = 0
x5
```
```array([0, 8, 5, 9, 2, 6, 2, 9, 4, 5, 1, 7])
```

1D vector to row vector

```x7 = x5.reshape(1, x5.shape[0])
x7
```
```array([[0, 8, 5, 9, 2, 6, 2, 9, 4, 5, 1, 7]])
```
```x8 = x5[np.newaxis, :]
x8
```
```array([[0, 8, 5, 9, 2, 6, 2, 9, 4, 5, 1, 7]])
```

Convert one-dimensional vector to column vector

```x7 = x5.reshape(x5.shape[0], 1)
x7
```
```array([[0],
[8],
[5],
[9],
[2],
[6],
[2],
[9],
[4],
[5],
[1],
[7]])
```
```x8 = x5[:, np.newaxis]
x8
```
```array([[0],
[8],
[5],
[9],
[2],
[6],
[2],
[9],
[4],
[5],
[1],
[7]])
```

Convert multi-dimensional vector to one-dimensional vector

```x6 = np.random.randint(0, 10, (3, 4))
x6
```
```array([[3, 7, 6, 4],
[4, 5, 6, 3],
[7, 6, 2, 3]])
```

flatten returns a copy

```x9 = x6.flatten()
x9
```
```array([3, 7, 6, 4, 4, 5, 6, 3, 7, 6, 2, 3])
```
```x9[0]=0
x6
```
```array([[3, 7, 6, 4],
[4, 5, 6, 3],
[7, 6, 2, 3]])
```

ravel returns a view

```x10 = x6.ravel()
x10
```
```array([3, 7, 6, 4, 4, 5, 6, 3, 7, 6, 2, 3])
```
```x10[0]=0
x6
```
```array([[0, 7, 6, 4],
[4, 5, 6, 3],
[7, 6, 2, 3]])
```

reshape returns the view

```x11 = x6.reshape(-1)
x11
```
```array([0, 7, 6, 4, 4, 5, 6, 3, 7, 6, 2, 3])
```
```x11[0]=10
x6
```
```array([[10,  7,  6,  4],
[ 4,  5,  6,  3],
[ 7,  6,  2,  3]])
```

### 10.3.5 Concatenation of arrays

```x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[0, 1, 2]])
```

1. Horizontal stitching - non-view

• hstack()
• c_
```x3 = np.hstack([x1, x2])
x3
```
```array([[1, 2, 3, 7, 8, 9],
[4, 5, 6, 0, 1, 2]])
```
```x3[0][0] = 0
x1
```
```array([[1, 2, 3],
[4, 5, 6]])
```
```x4 = np.c_[x1, x2]
x4
```
```array([[1, 2, 3, 7, 8, 9],
[4, 5, 6, 0, 1, 2]])
```
```x4[0][0] = 0
x1
```
```array([[1, 2, 3],
[4, 5, 6]])
```

2. Vertical stitching - non-view

• vstack()
• r_
```x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[0, 1, 2]])
```
```x5 = np.vstack([x1, x2])
x5
```
```array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 1, 2]])
```
```x6 = np.r_[x1, x2]
x6
```
```array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[0, 1, 2]])
```

### 10.3.6 Splitting an Array

1. Usage of split

```x6 = np.arange(10)
x6
```
```array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```
```x1, x2, x3 = np.split(x6, [2, 7]) #position of split point, forward (0-based)
print(x1, x2, x3)
```
```[0 1] [2 3 4 5 6] [7 8 9]
```

2. Usage of hsplit

```x7 = np.arange(1, 26).reshape(5, 5)
x7
```
```array([[ 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]])
```
```left, middle, right = np.hsplit(x7, [2,4])
print("left:\n", left)            # Columns 0~1
print("middle:\n", middle)        # Columns 2~3
print("right:\n", right)          # Column 4
```
```left:
[[ 1  2]
[ 6  7]
[11 12]
[16 17]
[21 22]]
middle:
[[ 3  4]
[ 8  9]
[13 14]
[18 19]
[23 24]]
right:
[[ 5]
[10]
[15]
[20]
[25]]
```

3. Usage of vsplit

```x7 = np.arange(1, 26).reshape(5, 5)
x7
```
```array([[ 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]])
```
```upper, middle, lower = np.vsplit(x7, [2,4])
print("upper:\n", upper)         # Lines 0~1
print("middle:\n", middle)       # Lines 2~3
print("lower:\n", lower)         # line 4
```
```upper:
[[ 1  2  3  4  5]
[ 6  7  8  9 10]]
middle:
[[11 12 13 14 15]
[16 17 18 19 20]]
lower:
[[21 22 23 24 25]]
```

## 10.4 Four major operations of Numpy

### 10.4.1 Vectorized Operations

1. Addition, subtraction, multiplication and division with numbers, etc. It can be seen that the whole vectorized operation has been carried out

```x1 = np.arange(1,6)
x1
```
```array([1, 2, 3, 4, 5])
```
```print("x1+5", x1+5)
print("x1-5", x1-5)
print("x1*5", x1*5)
print("x1/5", x1/5)
```
```x1+5 [ 6  7  8  9 10]
x1-5 [-4 -3 -2 -1  0]
x1*5 [ 5 10 15 20 25]
x1/5 [0.2 0.4 0.6 0.8 1. ]
```
```print("-x1", -x1)
print("x1**2", x1**2)
print("x1//2", x1//2)
print("x1%2", x1%2)
```
```-x1 [-1 -2 -3 -4 -5]
x1**2 [ 1  4  9 16 25]
x1//2 [0 1 1 2 2]
x1%2 [1 0 1 0 1]
```

2. Absolute value, trigonometric function, exponential, logarithm

(1) Absolute value

```x2 = np.array([1, -1, 2, -2, 0])
x2
```
```array([ 1, -1,  2, -2,  0])
```
```abs(x2)
```
```array([1, 1, 2, 2, 0])
```
```np.abs(x2)
```
```array([1, 1, 2, 2, 0])
```

(2) Trigonometric functions

```theta = np.linspace(0, np.pi, 3)
theta
```
```array([0.        , 1.57079633, 3.14159265])
```
```print("sin(theta)", np.sin(theta))
print("con(theta)", np.cos(theta))
print("tan(theta)", np.tan(theta))
```
```sin(theta) [0.0000000e+00 1.0000000e+00 1.2246468e-16]
con(theta) [ 1.000000e+00  6.123234e-17 -1.000000e+00]
tan(theta) [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]
```
```x = [1, 0 ,-1]
print("arcsin(x)", np.arcsin(x))
print("arccon(x)", np.arccos(x))
print("arctan(x)", np.arctan(x))
```
```arcsin(x) [ 1.57079633  0.         -1.57079633]
arccon(x) [0.         1.57079633 3.14159265]
arctan(x) [ 0.78539816  0.         -0.78539816]
```

(3) Exponential operation

```x = np.arange(3)
x
```
```array([0, 1, 2])
```
```np.exp(x)
```
```array([1.        , 2.71828183, 7.3890561 ])
```

(4) Logarithmic operation

```x = np.array([1, 2, 4, 8 ,10])
print("ln(x)", np.log(x))
print("log2(x)", np.log2(x))
print("log10(x)", np.log10(x))
```
```ln(x) [0.         0.69314718 1.38629436 2.07944154 2.30258509]
log2(x) [0.         1.         2.         3.         3.32192809]
log10(x) [0.         0.30103    0.60205999 0.90308999 1.        ]
```

3. Operations on two arrays

```x1 = np.arange(1,6)
x1
```
```array([1, 2, 3, 4, 5])
```
```x2 = np.arange(6,11)
x2
```
```array([ 6,  7,  8,  9, 10])
```
```print("x1+x2:", x1+x2)
print("x1-x2:", x1-x2)
print("x1*x2:", x1*x2)
print("x1/x2:", x1/x2)
```
```x1+x2: [ 7  9 11 13 15]
x1-x2: [-5 -5 -5 -5 -5]
x1*x2: [ 6 14 24 36 50]
x1/x2: [0.16666667 0.28571429 0.375      0.44444444 0.5       ]
```

### 10.4.2 Matrix Operations

```x = np.arange(9).reshape(3, 3)
x
```
```array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
```
• transpose of a matrix
```y = x.T
y
```
```array([[0, 3, 6],
[1, 4, 7],
[2, 5, 8]])
```
• matrix multiplication
```x = np.array([[1, 0],
[1, 1]])
y = np.array([[0, 1],
[1, 1]])
```
```x.dot(y)
```
```array([[0, 1],
[1, 2]])
```
```np.dot(x, y)
```
```array([[0, 1],
[1, 2]])
```
```y.dot(x)
```
```array([[1, 1],
[2, 1]])
```
```np.dot(y, x)
```
```array([[1, 1],
[2, 1]])
```

Note the difference with x*y, x*y is just multiplied by the corresponding position

```x*y
```
```array([[0, 0],
[1, 1]])
```

### 10.4.3 Broadcast operations

```x = np.arange(3).reshape(1, 3)
x
```
```array([[0, 1, 2]])
```
```x+5
```
```array([[5, 6, 7]])
```

rule

If the shapes of the two arrays do not match in dimension

Then the form of the array is expanded along the dimension 1 to match the shape of the other array.

```x1 = np.ones((3,3))
x1
```
```array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
```
```x2 = np.arange(3).reshape(1, 3)
x2
```
```array([[0, 1, 2]])
```
```x1+x2
```
```array([[1., 2., 3.],
[1., 2., 3.],
[1., 2., 3.]])
```
```x3 = np.logspace(1, 10, 10, base=2).reshape(2, 5)
x3
```
```array([[   2.,    4.,    8.,   16.,   32.],
[  64.,  128.,  256.,  512., 1024.]])
```
```x4 = np.array([[1, 2, 4, 8, 16]])
x4
```
```array([[ 1,  2,  4,  8, 16]])
```
```x3/x4
```
```array([[ 2.,  2.,  2.,  2.,  2.],
[64., 64., 64., 64., 64.]])
```
```x5 = np.arange(3).reshape(3, 1)
x5
```
```array([[0],
[1],
[2]])
```
```x6 = np.arange(3).reshape(1, 3)
x6
```
```array([[0, 1, 2]])
```
```x5+x6
```
```array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
```

### 10.4.4 Comparison operations and masks

1. Comparison operation

```x1 = np.random.randint(100, size=(10,10))
x1
```
```array([[37, 44, 58, 79,  1, 24, 85, 90, 27, 56],
[74, 68, 88, 27, 46, 34, 92,  1, 35, 45],
[84, 80, 83, 72, 98, 15,  4, 77, 14, 98],
[19, 85, 98, 32, 47, 50, 73,  3, 24,  2],
[ 5, 28, 26, 31, 48, 43, 72, 73, 53, 64],
[81, 87, 56, 59, 24, 42, 84, 34, 97, 65],
[74,  9, 41, 54, 78, 62, 53, 49,  8, 70],
[63, 44, 33, 35, 26, 83,  7, 14, 65, 84],
[57, 10, 62,  8, 74, 47, 90, 25, 78, 48],
[36, 31, 45, 39, 66, 82, 42, 25, 33, 84]])
```
```x1 > 50
```
```array([[False, False,  True,  True, False, False,  True,  True, False,
True],
[ True,  True,  True, False, False, False,  True, False, False,
False],
[ True,  True,  True,  True,  True, False, False,  True, False,
True],
[False,  True,  True, False, False, False,  True, False, False,
False],
[False, False, False, False, False, False,  True,  True,  True,
True],
[ True,  True,  True,  True, False, False,  True, False,  True,
True],
[ True, False, False,  True,  True,  True,  True, False, False,
True],
[ True, False, False, False, False,  True, False, False,  True,
True],
[ True, False,  True, False,  True, False,  True, False,  True,
False],
[False, False, False, False,  True,  True, False, False, False,
True]])
```

2. Manipulate Boolean Arrays

```x2 = np.random.randint(10, size=(3, 4))
x2
```
```array([[1, 4, 2, 9],
[8, 8, 2, 4],
[9, 5, 3, 6]])
```
```print(x2 > 5)
np.sum(x2 > 5)
```
```[[False False False  True]
[ True  True False False]
[ True False False  True]]

5
```
```np.all(x2 > 0)
```
```True
```
```np.any(x2 == 6)
```
```True
```
```np.all(x2 < 9, axis=1)   # Judging by row axis = 1. And if it is judged by column, then axis= 0;
```
```array([False,  True, False])
```
```x2
```
```array([[1, 4, 2, 9],
[8, 8, 2, 4],
[9, 5, 3, 6]])
```
```(x2 < 9) & (x2 >5)
```
```array([[False, False, False, False],
[ True,  True, False, False],
[False, False, False,  True]])
```
```np.sum((x2 < 9) & (x2 >5))
```
```3
```

3. Use a boolean array as a mask

```x2
```
```array([[1, 4, 2, 9],
[8, 8, 2, 4],
[9, 5, 3, 6]])
```
```x2 > 5
```
```array([[False, False, False,  True],
[ True,  True, False, False],
[ True, False, False,  True]])
```
```x2[x2 > 5]
```
```array([9, 8, 8, 9, 6])
```

After being used as a mask, the corresponding position of True will be taken out, and the corresponding position of False will be ignored

### 10.4.5 Fancy indexes

1. One-dimensional array

```x = np.random.randint(100, size=10)
x
```
```array([43, 69, 67,  9, 11, 27, 55, 93, 23, 82])
```

Note: The shape of the result is the same as the index array ind

```ind = [2, 6, 9]
x[ind]
```
```array([67, 55, 82])
```
```ind = np.array([[1, 0],
[2, 3]])
x[ind]
```
```array([[69, 43],
[67,  9]])
```

2. Multidimensional array

```x = np.arange(12).reshape(3, 4)
x
```
```array([[ 0,  1,  2,  3],
[ 4,  5,  6,  7],
[ 8,  9, 10, 11]])
```
```row = np.array([0, 1, 2])
col = np.array([1, 3, 0])
x[row, col]               # x(0, 1) x(1, 3) x(2, 0)
```
```array([1, 7, 8])
```
```row[:, np.newaxis]       # Column vector
```
```array([[0],
[1],
[2]])
```
```x[row[:, np.newaxis], col]    # broadcast mechanism
```
```array([[ 1,  3,  0],
[ 5,  7,  4],
[ 9, 11,  8]])
```

## 10.5 Other Numpy Common Functions

### 10.5.1 Numerical sorting

```x = np.random.randint(20, 50, size=10)
x
```
```array([48, 27, 44, 24, 34, 21, 24, 30, 34, 46])
```
• generate a new sorted array
```np.sort(x)
```
```array([21, 24, 24, 27, 30, 34, 34, 44, 46, 48])
```
```x
```
```array([48, 27, 44, 24, 34, 21, 24, 30, 34, 46])
```
• replace the original array
```x.sort()
x
```
```array([21, 24, 24, 27, 30, 34, 34, 44, 46, 48])
```
• get sorted index
```x = np.random.randint(20, 50, size=10)
x
```
```array([27, 36, 35, 28, 34, 20, 21, 49, 48, 30])
```
```i = np.argsort(x)
i
```
```array([5, 6, 0, 3, 9, 4, 2, 1, 8, 7], dtype=int64)
```

### 10.5.2 Maximum and minimum

```x = np.random.randint(20, 50, size=10)
x
```
```array([48, 31, 30, 44, 48, 33, 44, 48, 39, 35])
```
```print("max:", np.max(x))
print("min:", np.min(x))
```
```max: 48
min: 30
```
```print("max_index:", np.argmax(x))
print("min_index:", np.argmin(x))
```
```max_index: 0
min_index: 2
```

### 10.5.3 Numerical Summation, Multiplication

```x = np.arange(1,6)
x
```
```array([1, 2, 3, 4, 5])
```
```x.sum()
```
```15
```
```np.sum(x)
```
```15
```
```x1 = np.arange(6).reshape(2,3)
x1
```
```array([[0, 1, 2],
[3, 4, 5]])
```
• sum by row
```np.sum(x1, axis=1)
```
```array([ 3, 12])
```
• sum by column
```np.sum(x1, axis=0)
```
```array([3, 5, 7])
```
• summation of the whole
```np.sum(x1)
```
```15
```
• multiply
```x
```
```array([1, 2, 3, 4, 5])
```
```x.prod()
```
```120
```
```np.prod(x)
```
```120
```

### 10.5.4 Median, Mean, Variance, Standard Deviation

```x = np.random.normal(0, 1, size=10000)
```
```import matplotlib.pyplot as plt

plt.hist(x, bins=50)
plt.show()
```

• median
```np.median(x)
```
```-0.01024418366119727
```
• mean
```x.mean()
```
```-0.004164442327293362
```
```np.mean(x)
```
```-0.004164442327293362
```
• variance
```x.var()
```
```1.0221853234535774
```
```np.var(x)
```
```1.0221853234535774
```
• standard deviation
```x.std()
```
```1.0110318112965473
```
```np.std(x)
```
```1.0110318112965473
```

Tags: Python numpy

Posted by yacaph on Thu, 06 Oct 2022 09:53:22 +0300