# Python notes 1 - numpy section

Start to sort out the important modules of python and the parts that you often forget. First, let's study and sort out numpy. First of all, numpy (Numerical Python) is a very important library of python. It is also a program library that I often use in my study and work process. It is mainly used for array or matrix calculation and is suitable for linear algebra calculation.
numpy often and SciPy (Scientific Python) and Matplotlib (used for drawing) basically includes most functions of MatLab. This combination is widely used to replace MatLab, which is a powerful scientific computing environment.
References for the entire note are from the rookie tutorial 1.

# 1 array properties

## 1.1 basic introduction

The dimension of NumPy array is the number of axes, that is, the dimension of array. In NumPy, every linear array is called an axis, that is, dimensions. For example, a two-dimensional array is equivalent to two one-dimensional arrays, in which each element in the first one is a one-dimensional array. So the one-dimensional array is the axis in NumPy. The first axis is the same as the bottom array. The second axis is the array in the bottom array. The number of axes is the dimension of the array.
Many times you can declare axis. axis=0 means to operate along the 0 axis, that is, to operate on each column; axis=1 means to operate along the 1 axis, that is, to operate on each row.
The important darray object properties in NumPy's array are:
One ndarray.ndim : number of axes or dimensions
Two ndarray.shape : Dimension of array, for matrix, n rows and m columns
Three ndarray.size : the total number of array elements, equivalent to the value of n*m in. shape
Four ndarray.dtype : element type of the ndarray object
Five ndarray.itemsize : the size, in bytes, of each element in the ndarray object
Six ndarray.flags : memory information for the ndarray object
Seven ndarray.real : real part of the ndarray element
Eight ndarray.imag : virtual part of the ndarray element
Nine ndarray.data : the buffer containing the actual array elements. Since the elements are usually obtained through the index of the array, this attribute is not usually needed.

## 1.2 ndarray.ndim

import numpy as np
a = np.arange(24)
print (a.ndim)  # a now there is only one dimension
# Now resize it
b = a.reshape(2,4,3)  # b now has three dimensions
print (b.ndim)

## 1.3 ndarray.shape

ndarray.shape Represents the dimension of an array, and returns a tuple. The length of the tuple is the number of dimensions, that is, the ndim attribute. For example, a two-dimensional array with dimensions representing "number of rows" and "number of columns".
ndarray.shape It can also be used to resize an array.

import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print (a.shape)
###### Resize array
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
a.shape = (3,2)
print (a)
### Output from two rows, three columns matrix or array to three rows, two columns matrix or array
###### NumPy also provides the reshape function to resize the array.
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)

## 1.4 ndarray.itemsize

ndarray.itemsize Returns the size of each element in the array in bytes.
For example, the value of itemsize attribute of an array with element type of float64 is 8(float64 occupies 64 bits, each byte is 8, so 64 / 8 occupies 8 bytes). For example, the attribute of item of an array with element type of complex32 is 4 (32 / 8).

import numpy as np
###### dtype of array is int8 (one byte)
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize)
### Output 1
###### The dtype of the array is now float64 (eight bytes)
y = np.array([1,2,3,4,5], dtype = np.float64)
print (y.itemsize)
### Output 8

## 1.5 ndarray.flags

ndarray.flags Returns the memory information of the ndarray object, including the following properties:
1 C_ Continuuus ©: data is in a single C-style continuous segment
2 F_ Continuuus (f): data is in a single Fortran style continuous segment
3 OWNDATA (O): an array has the memory it uses or borrows it from another object
4 WRITEABLE (W): the data area can be written. If the value is set to False, the data is read-only
5 ALIGNED (A): data and all elements are properly aligned to the hardware
6 UPDATEIFCOPY (U): this array is a copy of other arrays. When this array is released, the contents of the original array will be updated

import numpy as np
x = np.array([1,2,3,4,5])
print (x.flags)

# 2 create an N-dimensional array object

## 2.1 general types

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
### object: array or nested sequence
### dtype: data type of array element, optional, which will be explained later
### copy: whether the object needs to be copied, optional
### order: the style to create an array. C is the row direction, F is the column direction, and A is any direction (default)
### subok: returns an array of the same type as the base class by default
### ndmin: Specifies the minimum dimension of the generated array
###### e.g.
import numpy as np
a = np.array([1,2,3])
print (a)

## 2.2 creating uninitialized arrays of specified data types and shapes

numpy.empty(shape, dtype = float, order = 'C')
### Shape: array shape, that is, how many rows and columns are defined
### dtype: data type, optional, to be specified later
### Order: there are "C" and "F" options, which respectively represent row priority and column priority. The order of storage elements in the computer memory, that is to say, decide whether to read from row or column
###### e.g.
import numpy as np
x = np.empty([4,3], dtype = int)
print(x)
### The array elements of the output are random values because they are not initialized.

## 2.3 create an array of the specified shape with zero array element

numpy.zeros(shape, dtype = float, order = 'C')
###### e.g.
import numpy as np
# Floating point by default
x = np.zeros(5)
print(x)
# Set type to integer
y = np.zeros((5,), dtype = np.int)
print(y)
# You can also customize the type
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])
print(z)

## 2.4 create an array of the specified shape with array element 1

You can create arrays with zero elements, as well as arrays with one element.

numpy.ones(shape, dtype = None, order = 'C')
### order: 'C' for row array of C, or 'F' for column array of FORTRAN
###### e.g.
import numpy as np
# Floating point by default
x = np.ones(5)
print(x)
# Custom type
x = np.ones([2,2], dtype = int) # Running through python, we found that the output of [2,2] and (2,2) are the same
print(x)

# 3 data type of array element

## 3.1 basic introduction

NumPy supports a lot more data types than Python built-in types, which can basically correspond to the data types of C language, some of which correspond to Python built-in types. The following table lists the common NumPy basic types.

name describe
bool_ Boolean data type (True or False)
int_ Default integer type (similar to long, int32 or int64 in C)
intc Like the int type of C, it is int32 or int 64 in general
intp Integer type used for index (similar to ssize of C_ t. int32 or int64 in general)
int8 Bytes (- 128 to 127)
int16 Integer (- 32768 to 32767)
int32 Integer (- 2147483648 to 2147483647)
int64 Integer (- 9223372036854775808 to 9223372036854775807)
uint8 Unsigned integer (0 to 255)
uint16 Unsigned integer (0 to 65535)
uint32 Unsigned integer (0 to 4294967295)
uint64 Unsigned integer (0 to 18446744073709551615)
float_ Shorthand for float64 type
float16 Semi precision floating-point number, including: 1 sign bit, 5 fingers, 10 tails
float32 Single precision floating-point number, including: 1 sign bit, 8 fingers, 23 tails
float64 Double precision floating-point number, including: 1 sign bit, 11 fingers, 52 tails
complex_ Short for complex128 type, i.e. 128 bit complex
complex64 Complex number, indicating double 32-bit floating-point number (real part and imaginary part)
complex128 Complex number, indicating double 64 bit floating-point number (real part and imaginary part)

## 3.2 data type object (dtype)

The data type object is used to describe how to use the memory area corresponding to the array, which depends on the following aspects:
1 type of data (integer, floating point, or Python object)
2 size of data (for example, how many bytes are used for integer storage)
3 byte order of data (small end method or large end method)
4 in the case of structured type, the name of the field, the data type of each field and the part of the memory block taken by each field
5 if the data type is a subarray, its shape and data type
Byte order is determined by pre setting "< or" > "Means the small end method (the minimum value is stored in the smallest address, i.e. the low group is placed in the front)." >"Means big endian (the most important byte is stored at the smallest address, that is, the high-order group is placed at the top).
dtype objects are constructed using the following syntax:

numpy.dtype(object, align, copy)
### Object - data type object to convert to
### align - if true, populates the field to look like a C-like structure.
### copy - copies the dtype object. If false, it is a reference to the built-in data type object

## 3.3 Example

import numpy as np
# Use scalar type
dt = np.dtype(np.int32)
print(dt)
### ------------------------------------------------------------------------------
import numpy as np
# Int8, int16, int32, and Int64 can be replaced by strings' I1 ',' I2 ',' I4 ', and' I8 '
dt = np.dtype('i4')
print(dt)
### ------------------------------------------------------------------------------
import numpy as np
# Byte order annotation
dt = np.dtype('<i4')
print(dt)
### ------------------------------------------------------------------------------
# Apply data types to the ndarray object
import numpy as np
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a) ### output: [(10,) (20,) (30,)]
print(a['age']) ### output: [10 20 30]
### ------------------------------------------------------------------------------
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a) ### output: [('abc', 21, 50.0) ('xyz', 18, 75.0)]
print(a['name']) ### output: ['abc' 'xyz']

## 3.4 character code that uniquely defines the built-in type (to be further understood)

Each built-in type has a character code that uniquely defines it, as follows:

character Corresponding type
b Boolean
i (signed) integer
u Unsigned integer
f float
c Complex floating point
m timedelta (time interval)
M Datetime (datetime)
O (Python) object
S, a (byte -) string
U Unicode
V Original data (void)

# 4 more ways to create arrays

## 4.1 NumPy creates an array from an existing array

### 4.1.1 numpy.asarray

numpy.asarray(a, dtype = None, order = None)
### a: Any form of input parameter can be, list, tuple of list, tuple, tuple of tuple, tuple list, multidimensional array
######----------------------------------------------------------------------------
### e.g.
### Convert list to ndarray
x =  [1,2,3]
a = np.asarray(x)
print (a)  ### output: [1  2  3]
### Convert tuple list to ndarray
x =  [(1,2,3),(4,5)]
a = np.asarray(x)
print (a)  ### output: [(1, 2, 3) (4, 5)]
### You can also set dtype parameters
x =  [1,2,3]
a = np.asarray(x, dtype =  float)
print (a)  ### output: [ 1.  2.  3.]

### 4.1.2 numpy.frombuffer

numpy.frombuffer Used to implement dynamic arrays.
numpy.frombuffer Accept the buffer input parameter, read it in as a stream, and convert it to a darray object.

numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
### Note: when buffer is a string, python 3's default STR is Unicode, so you need to convert it to bytestring and add b before the original str.
### buffer: it can be any object and will be read in the form of stream
### count: the number of data read. The default value is - 1. Read all data
### offset: the starting position of the read. The default is 0
######----------------------------------------------------------------------------
### e.g.
### python 3.0 edition
import numpy as np
s =  b'Hello World'
a = np.frombuffer(s, dtype =  'S1')
print (a) ### output: [b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
### python 2.0 edition
s =  'Hello World'
a = np.frombuffer(s, dtype =  'S1')
print (a) ### output: ['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']

### 4.1.3 numpy.fromiter

numpy.fromiter Method to create an ndarray object from an iteratable object and return a one-dimensional array.

numpy.fromiter(iterable, dtype, count=-1)
### iterable: iteratable object
### count: the number of data read. The default value is - 1. Read all data
######----------------------------------------------------------------------------
### e.g.
# Using the range function to create a list object
list=range(5)
it=iter(list)
# Creating a ndarray using an iterator
x=np.fromiter(it, dtype=float)
print(x) ### output: [0. 1. 2. 3. 4.]

## 4.2 NumPy creating arrays from numeric ranges

### 4.2.1 numpy.arange

Using the range function in the numpy package to create a numeric range and return the ndarray object

numpy.arange(start, stop, step, dtype)
### Start: start value, default is 0
### Stop: stop value (not included)
### Step: step, default is 1
###### e.g.
import numpy as np
x = np.arange(5)
print (x) ### output: [0  1  2  3  4]
### Start value, end value and step length are set
import numpy as np
x = np.arange(10,20,2)
print (x) ### output: [10  12  14  16  18]

### 4.2.2 numpy.linspace

numpy.linspace Function is used to create a one-dimensional array, which is composed of a sequence of equal differences

np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
### Start: start value of the sequence
### stop: the ending value of the sequence. If the endpoint is true, the value is included in the sequence
### num: number of equal step samples to be generated, default is 50
### endpoint: when the value is True, the sequence contains the stop value. Otherwise, it does not. The default value is True.
### retstep: if it is True, the generated array will display the spacing, otherwise it will not display.
###### e.g.
### Three parameters are used in this example. The starting point is set to 1, the ending point is set to 10, and the number of sequences is set to 10
import numpy as np
a = np.linspace(1,10,10)
print(a) ### output: [ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
### Set the equal difference sequence with all elements of 1
import numpy as np
a = np.linspace(1,1,10)
print(a) ### output: [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
### This instance sets the spacing
a =np.linspace(1,10,10,retstep= True)
print(a)
# Examples of expansion
b =np.linspace(1,10,10).reshape([10,1])
print(b)
### output:
### (array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.]), 1.0)
### [[ 1.]
###  [ 2.]
###  [ 3.]
###  [ 4.]
###  [ 5.]
###  [ 6.]
###  [ 7.]
###  [ 8.]
###  [ 9.]
###  [10.]]

### 4.2.3 numpy.logspace

numpy.logspace Function is used to create a series of equal ratio numbers

np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
### Start: the starting value of the sequence is: base ** start
### Stop: the end value of the sequence is: base ** stop. If endpoint is true, the value is contained in the sequence
### num: number of equal step samples to be generated, default is 50
### endpoint: when the value is True, the sequence contains the stop value. Otherwise, it does not. The default value is True.
### Base: base of log.
###### e.g.
import numpy as np
# The default base is 10
a = np.logspace(1.0,  2.0, num =  10)
print (a)
### output:
### [ 10.           12.91549665     16.68100537      21.5443469  27.82559402
###   35.93813664   46.41588834     59.94842503      77.42636827    100.    ]
### Set base of logarithm to 2
import numpy as np
a = np.logspace(0,9,10,base=2)
print (a) ### output: [  1.   2.   4.   8.  16.  32.  64. 128. 256. 512.]

# 5 index

## 5.1 basic operation of slicing and indexing

The contents of the ndarray object can be accessed and modified by index or slice, just like the slice operation of list in Python.
The ndarray array can be indexed based on the subscript of 0 - n, and the slice object can be cut from the original array by setting the start, stop and step parameters through the built-in slice function.
The following is a series of examples to introduce the basic operation of index.

import numpy as np
######----------------------------------------------------------------------------
### Using slice() function
a = np.arange(10)
s = slice(2,7,2)   # From index 2 to index 7, every 2
print (a[s]) # or print(a[slice(2,7,2)])
### output: [2  4  6]
######----------------------------------------------------------------------------
a = np.arange(10)
b = a[2:7:2]   # From index 2 to index 7, every 2
print(b)
### output: [2  4  6]
######----------------------------------------------------------------------------
a = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]
b = a[5]
print(b)
### output: 5
######----------------------------------------------------------------------------
### Apply to multidimensional arrays
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# Cut from an index
print('Index from array a[1:] Start cutting at')
print(a[1:])
### output:
### [[1 2 3]
###  [3 4 5]
###  [4 5 6]]
### Cut from array index a[1:]
### [[3 4 5]
###  [4 5 6]]
######----------------------------------------------------------------------------
### Slices can also include ellipsis , so that the length of the selection tuple is the same as the dimension of the array. If you use an ellipsis at the row location, it returns the ndarray that contains the elements in the row.
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1])   # Column 2 elements
print (a[1,...])   # Line 2 element
print (a[...,1:])  # Column 2 and all remaining elements
### output:
### [2 4 5]
### [3 4 5]
### [[2 3]
###  [4 5]
###  [5 6]]

### 5.2.1 integer array index

### Gets the elements at positions (0,0), (1,1) and (2,0) in the array.
import numpy as np
x = np.array([[1,  2],  [3,  4],  [5,  6]])
y = x[[0,1,2],  [0,1,0]]  # The left array is the index of row position, the right array is the index of column position, and one-to-one correspondence. The position of elements in the left and right array is the position of output result
print (y) # output: [1  4  5]
######----------------------------------------------------------------------------
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print (y)
### output:
### [[ 0  2]
###  [ 9 11]]
### OR
y = x[[0,0,3,3],[0,2,0,2]]
print (y) ### output: [ 0  2  9 11]
######----------------------------------------------------------------------------
a = np.array([[1,2,3], [4,5,6],[7,8,9]])
b = a[1:3, 1:3]
c = a[1:3,[1,2]]
d = a[...,1:]
print(b)
print(c)
print(d)
### output:
### [[5 6]
###  [8 9]]
### [[5 6]
###  [8 9]]
### [[2 3]
###  [5 6]
###  [8 9]]

### 5.2.2 Boolean index

We can index the target array through a Boolean array.
A Boolean index uses a Boolean operation, such as a comparison operator, to get an array of elements that meet the specified criteria.

### Get elements greater than 5
import numpy as np
x = np.array([[  0,  1,  2],[  3,  4,  5],[  6,  7,  8],[  9,  10,  11]])
print ('Our array is:')
print (x)
print ('\n')
# Now we will print out elements larger than 5
print  ('Elements greater than 5 are:')
print (x[x > 5])
### output:
### Our array is:
### [[ 0  1  2]
###  [ 3  4  5]
###  [ 6  7  8]
###  [ 9 10 11]]
###
###
### Elements greater than 5 are:
### [ 6  7  8  9 10 11]
######----------------------------------------------------------------------------
### Use the complement operator to filter NaN.
a = np.array([np.nan,  1,2,np.nan,3,4,5])
print (a[~np.isnan(a)]) # np.isnan () and  np.nan () function
### output: [ 1.   2.   3.   4.   5.]
######----------------------------------------------------------------------------
### Shows how to filter out non complex elements from an array.
a = np.array([1,  2+6j,  5,  3.5+5j])
print (a[np.iscomplex(a)]) # np.iscomplex() function
### output: [2.0+6.j  3.5+5.j]

### 5.2.3 fancy index

Fancy index refers to the use of integer array for index.
The fancy index takes the value of the index array as the index of an axis of the target array. For using one-dimensional integer array as index, if the target is one-dimensional array, the result of index is the element of corresponding position; if the target is two-dimensional array, it is the row of corresponding subscript.
Unlike slicing, a fancy index always copies data to a new array.

###### Incoming sequence index array
import numpy as np
x=np.arange(32).reshape((8,4))
print (x[[4,2,1,7]])
### output:
### [[16 17 18 19]
###  [ 8  9 10 11]
###  [ 4  5  6  7]
###  [28 29 30 31]]

###### Incoming inverted index array
x=np.arange(32).reshape((8,4))
print (x[[-4,-2,-1,-7]])
### output:
### [[16 17 18 19]
###  [24 25 26 27]
###  [28 29 30 31]
###  [ 4  5  6  7]]

###### Pass in multiple index arrays (to use np.ix_ )
x=np.arange(32).reshape((8,4))
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
### output:
### [[ 4  7  5  6]
###  [20 23 21 22]
###  [28 31 29 30]
###  [ 8 11  9 10]]
### notes:
### np.xi_  If you enter two lists, the first list stores the row labels of the elements to be extracted, and the second list stores the column labels of the elements to be extracted
### Each element in a list traverses each value in the second list to form a row of elements in the new matrix.

Broadcast is numpy's way of numerical calculation for arrays of different shapes. The arithmetic operation of arrays is usually performed on the corresponding elements.
If the shapes of two arrays a and B are the same, that is to say, a.shape == b.shape, then the result of a*b is the multiplication of corresponding bits of array A and B. This requires the same dimensions and the same length of each dimension.
When the shape of two arrays in the operation is different, numpy will automatically trigger the broadcast mechanism. For example:
Adding 4x3 two-dimensional array and 3-dimensional array is equivalent to repeating array b four times in two-dimensional.

### e.g.
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
### output:
### [[ 1  2  3]
###  [11 12 13]
###  [21 22 23]
###  [31 32 33]]
###### Equivalent to
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
bb = np.tile(b, (4, 1))  # Repeat the dimensions of b
print(a + bb)
### output:
### [[ 1  2  3]
###  [11 12 13]
###  [21 22 23]
###  [31 32 33]]

1. Let all input arrays be aligned with the array with the longest shape, and the insufficient parts in the shape are supplemented by adding 1 in front.
2 the shape of the output array is the maximum value on each dimension of the input array shape.
3 if the length of a dimension of the input array and the corresponding dimension of the output array are the same or their length is 1, the array can be used for calculation, otherwise an error occurs.
4 when the length of a dimension of the input array is 1, the first set of values on this dimension will be used for operation along this dimension.
Simple understanding: for two arrays, compare each dimension of them respectively (ignore if one array has no current dimension), which meets the following requirements:
1 array has the same shape.
2 the value of the current dimension is equal.
3 one of the values of the current dimension is 1.
4 if the conditions are not met, an exception of "ValueError: frames are not aligned" will be thrown.
To understand the title(): tile() function is to copy the original matrix horizontally and vertically.

tile(mat, (1, 4))  ### Quadruple column copy
np.ones((2,3))
### Equivalent to
np.tile(1., (2,3))
######----------------------------------------------------------------------------
np.zeros((2,3))
### Equivalent to
np.tile(0., (2,3))

# 7-fold algebra group

## 7.1 basic operation

NumPy iterator object numpy.nditer Provides a flexible way to access one or more array elements. The most basic task of iterator is to access array elements. I.e. use nditer() to iterate

import numpy as np
a = np.arange(6).reshape(2,3)
print ('The original array is:')
print (a)
print ('\n')
print ('Iteration output element:')
for x in np.nditer(a):
print (x, end=", " )
### output:
### The original array is:
### [[0 1 2]
###  [3 4 5]]
###
###
### Iteration output element:
### 0, 1, 2, 3, 4, 5,

The above example does not use the standard C or Fortran order. The order selected is consistent with the array memory layout. This is to improve the access efficiency. The default is row major order (or C-order).
This reflects the fact that by default you only need to access each element, regardless of its specific order. We can see this by iterating the above array transposition, and compare it with the copy mode of accessing array transposition in C order, as shown in the following example:

import numpy as np
a = np.arange(6).reshape(2,3)
for x in np.nditer(a.T): # a. Transposition of t-representative matrix
print (x, end=", " )
print ('\n')
for x in np.nditer(a.T.copy(order='C')):  ### copy() function
print (x, end=", " )
### output:
### 0, 1, 2, 3, 4, 5,
###
### 0, 3, 1, 4, 2, 5,

From the above example, we can see that the traversal order of a and a.T is the same, that is, their storage order in memory is the same, but the traversal result of a.T.copy(order = 'C') is different, because it is different from the first two storage methods, and the default is row by row access.

## 7.2 control traversal sequence

for x in np.nditer (a, order = 'F'): Fortran order, i.e. rank first; for x in np.nditer(a.T, order = 'C'): C order, that is, row order takes precedence.

import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('The original array is:')
print (a)
print ('\n')
print ('The transpose of the original array is:')
b = a.T
print (b)
print ('\n')
print ('with C Style order:')
c = b.copy(order='C')
print (c)
for x in np.nditer(c):
print (x, end=", " )
print  ('\n')
print  ('with F Style order:')
c = b.copy(order='F')
print (c)
for x in np.nditer(c):
print (x, end=", " )
### output:
### The original array is:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
###
###
### The transpose of the original array is:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
###
###
### In C-style order:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
### 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,
###
### Sort in F-style order:
### [[ 0 20 40]
###  [ 5 25 45]
###  [10 30 50]
###  [15 35 55]]
### 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
######----------------------------------------------------------------------------
### You can force the nditer object to use a certain order by setting it explicitly
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('The original array is:')
print (a)
print ('\n')
print ('with C Style order:')
for x in np.nditer(a, order =  'C'):
print (x, end=", " )
print ('\n')
print ('with F Style order:')
for x in np.nditer(a, order =  'F'):
print (x, end=", " )
### output:
### The original array is:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
###
###
### In C style order:
### 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,
###
### Sort in F-style order:
### 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

## 7.3 modifying the value of an element in an array

The Diter object has another optional parameter op_flags. By default, nditer regards the array to be iterated as read-only. In order to traverse the array and modify the array elements, read-write or write only mode must be specified.

import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('The original array is:')
print (a)
print ('\n')
x[...]=2*x
print ('The modified array is:')
print (a)
### output:
### The original array is:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
###
###
### The modified array is:
### [[  0  10  20  30]
###  [ 40  50  60  70]
###  [ 80  90 100 110]]

## 7.4 use of external circulation

The constructor of the nditer class has the flags parameter, which accepts the following values:

parameter describe
c_index Index that can track C-order
f_index Indexes that can track Fortran order
multi-index One index type can be tracked per iteration
external_loop The given value is a one-dimensional array with multiple values, not a zero dimensional array
### "external_loop "iterator traverses each column and combines them into a one-dimensional array.
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('The original array is:')
print (a)
print ('\n')
print ('The modified array is:')
for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):
print (x, end=", " )
### output:
### The original array is:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
###
###
### The modified array is:
### [ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

If two arrays are broadcast, the nditer composite object can iterate over them at the same time. Assuming that the dimension of array A is 3X4 and the dimension of array b is 1X4, the following iterators are used (the size of array b broadcast to a).

import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print  ('The first array is:')
print (a)
print  ('\n')
print ('The second array is:')
b = np.array([1,  2,  3,  4], dtype =  int)
print (b)
print ('\n')
print ('The modified array is:')
for x,y in np.nditer([a,b]):
print ("%d:%d"  %  (x,y), end=", " )
### output:
### The first array is:
### [[ 0  5 10 15]
###  [20 25 30 35]
###  [40 45 50 55]]
###
###
### The second array is:
### [1 2 3 4]
###
###
### The modified array is:
### 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,

# Basic processing of array

## 8.1 modifying array shape

### 8.1.1 numpy.reshape

numpy.reshape(arr, newshape, order='C')
### arr: array of shapes to modify
### newshape: integer or array of integers. The new shape should be compatible with the original shape
### Order: 'C' -- by row, 'F' -- by column, 'A' -- original order, 'k' -- order in which elements appear in memory.
###### e.g.
import numpy as np
a = np.arange(8)
print ('Original array:')
print (a)
b = a.reshape(4,2)
print ('Modified array:')
print (b)
### OR
b = np.reshape(a,(4,2))
print ('Modified array:')
print (b)
### output:
### Original array:
### [0 1 2 3 4 5 6 7]
### Modified array:
### [[0 1]
###  [2 3]
###  [4 5]
###  [6 7]]
### Modified array:
### [[0 1]
###  [2 3]
###  [4 5]
###  [6 7]]

### 8.1.2 numpy.ndarray.flat

numpy.ndarray.flat Is an array element iterator

import numpy as np
a = np.arange(9).reshape(3,3)
print ('Original array:')
for row in a:
print (row)
#Each element in the array is processed. You can use the flat attribute, which is an array element iterator:
print ('Array after iteration:')
for element in a.flat:
print (element)
### output:
### Original array:
### [0 1 2]
### [3 4 5]
### [6 7 8]
### Array after iteration:
### 0
### 1
### 2
### 3
### 4
### 5
### 6
### 7
### 8

### 8.1.3 numpy.ndarray.flatten

numpy.ndarray.flatten Returns a copy of the array. Changes made to the copy do not affect the original array.

ndarray.flatten(order='C')
### Order: 'C' -- by row, 'F' -- by column, 'A' -- original order, 'K' -- order in which elements appear in memory.
###### e.g.
import numpy as np
a = np.arange(8).reshape(2,4)
print ('Original array:')
print (a)
# Default by line
print ('Expanded array:')
print (a.flatten())
print ('with F Array expanded in style order:')
print (a.flatten(order = 'F'))
### output:
### Original array:
### [[0 1 2 3]
###  [4 5 6 7]]
### Expanded array:
### [0 1 2 3 4 5 6 7]
### Arrays expanded in F-style order:
### [0 4 1 5 2 6 3 7]

### 8.1.4 numpy.ravel

numpy.ravel() flattened array elements, usually in "C-style" order, return the array view (view, a bit similar to the reference of C/C + +), the modification will affect the original array.

numpy.ravel(a, order='C')
### Order: 'C' -- by row, 'F' -- by column, 'A' -- original order, 'K' -- order in which elements appear in memory.
###### e.g.
import numpy as np
a = np.arange(8).reshape(2,4)
print ('Original array:')
print (a)
print ('call ravel After function:')
print (a.ravel())
print ('with F Style sequence call ravel After function:')
print (a.ravel(order = 'F'))
### output:
### Original array:
### [[0 1 2 3]
###  [4 5 6 7]]
### After calling the t ravel function:
### [0 1 2 3 4 5 6 7]
### After calling the t ravel function in F-style order:
### [0 4 1 5 2 6 3 7]

## 8.2 flip array

### 8.2.1 numpy.transpose & numpy.ndarray.T

numpy.transpose Function is used to change the dimensions of an array, similar to the transposition of a matrix.

numpy.transpose(arr, axes)
### arr: array to operate on
### axes: integer list, corresponding dimension, usually all dimensions will be swapped.
###### e.g.
import numpy as np
a = np.arange(12).reshape(3,4)
print ('Original array:')
print (a )
print ('Commutation array:')
print (np.transpose(a))
### output:
### Original array:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### Commutation array:
### [[ 0  4  8]
###  [ 1  5  9]
###  [ 2  6 10]
###  [ 3  7 11]]
###### numpy.ndarray.T similar numpy.transpose
a = np.arange(12).reshape(3,4)
print ('Original array:')
print (a)
print ('Transpose array:')
print (a.T)
### output:
### Original array:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### Transpose array:
### [[ 0  4  8]
###  [ 1  5  9]
###  [ 2  6 10]
###  [ 3  7 11]]

### 8.2.2 numpy.rollaxis

numpy.rollaxis Function to scroll a specific axis backward to a specific position

numpy.rollaxis(arr, axis, start)
### arr: array
### axis: the relative position of other axes will not change
### start: zero by default, indicating complete scrolling. Scroll to a specific location
###### e.g.
import numpy as np
# Created a 3D darray
a = np.arange(8).reshape(2,2,2)
print ('Original array:')
print (a)
# Scroll axis 2 to axis 0 (width to depth)
print ('call rollaxis Function:')
print (np.rollaxis(a,2))
# Scroll axis 0 to axis 1: (width to height)
print ('call rollaxis Function:')
print (np.rollaxis(a,2,1))
### output:
### Original array:
### [[[0 1]
###   [2 3]]
###
###  [[4 5]
###   [6 7]]]
### Call the rollaxis function:
### [[[0 2]
###   [4 6]]
###
###  [[1 3]
###   [5 7]]]
### Call the rollaxis function:
### [[[0 2]
###   [1 3]]
###
###  [[4 6]
###   [5 7]]]

### 8.2.3 numpy.swapaxes

numpy.swapaxes Function to exchange two axes of an array.

numpy.swapaxes(arr, axis1, axis2)
### arr: array of inputs
### axis1: integer corresponding to the first axis
### axis2: integer corresponding to the second axis
###### e.g.
import numpy as np
# Created a 3D darray
a = np.arange(8).reshape(2,2,2)
print ('Original array:')
print (a)
# Now swap axis 0 (depth direction) to axis 2 (width direction)
print ('call swapaxes Array after function:')
print (np.swapaxes(a, 2, 0))
### output:
### Original array:
### [[[0 1]
###   [2 3]]
###
###  [[4 5]
###   [6 7]]]
### Array after calling the swaaxes function:
### [[[0 4]
###   [2 6]]
###
###  [[1 5]
###   [3 7]]]

## 8.3 modifying array dimensions

numpy.broadcast An object used to mimic broadcasting that returns an object that encapsulates the result of broadcasting one array to another.
This function uses two arrays as input parameters.

###### Try to understand ######
import numpy as np
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
# It has the iterator property, based on its own component's iterator tuple
r,c = b.iters
# Python 3. X is next(context), python 2. X is context.next()
print (next(r), next(c))
print (next(r), next(c))
# The shape property returns the shape of the broadcast object
print (b.shape)
print ('\n')
c = np.empty(b.shape)
print (c.shape)
c.flat = [u + v for (u,v) in b]
print ('call flat Function:')
print (c)
# Same results as NumPy's built-in broadcast support
print ('x And y Of and:')
print (x + y)

### output:
### 1 4
### 1 5
### (3, 3)
### (3, 3)
### Call the flat function:
### [[5. 6. 7.]
###  [6. 7. 8.]
###  [7. 8. 9.]]
### Sum of x and y:
### [[5 6 7]
###  [6 7 8]
###  [7 8 9]]

NumPy.broadcast_ The to function broadcasts the array to the new shape. It returns a read-only view on the original array. It is usually discontinuous. If the new shape does not conform to NumPy's broadcast rules, the function may throw ValueError.

###### e.g.
import numpy as np
a = np.arange(4).reshape(1,4)
print ('Original array:')
print (a)
### output:
### Original array:
### [[0 1 2 3]]
### Call broadcast_ After the to function:
### [[0 1 2 3]
###  [0 1 2 3]
###  [0 1 2 3]
###  [0 1 2 3]]

### 8.3.3 numpy.expand_dims

numpy.expand_ The dims function extends the shape of an array by inserting a new axis at a specified location

numpy.expand_dims(arr, axis)
### arr: input array
### Axis: position of new axis insertion
###### e.g.
import numpy as np
x = np.array(([1,2],[3,4]))
print ('array x: ')
print (x)
y = np.expand_dims(x, axis = 0)
print ('array y: ')
print (y)
print ('array x and y Shape of:')
print (x.shape, y.shape)
# Insert axis in position 1
y = np.expand_dims(x, axis = 1)
print ('Array after inserting axis at position 1 y: ')
print (y)
print ('x.ndim and y.ndim: ')
print (x.ndim,y.ndim)
print ('x.shape and y.shape: ')
print (x.shape, y.shape)
### output:
### Array x:
### [[1 2]
###  [3 4]]
### Array y:
### [[[1 2]
###   [3 4]]]
### Shape of arrays x and y:
### (2, 2) (1, 2, 2)
### Array y after inserting axis at position 1:
### [[[1 2]]
###
###  [[3 4]]]
### x.ndim and y.ndim:
### 2 3
### x.shape and y.shape:
### (2, 2) (2, 1, 2)

### 8.3.4 numpy.squeeze

numpy.squeeze Function to remove a one-dimensional entry from the shape of a given array

numpy.squeeze(arr, axis)
### arr: input array
### axis: integer or integer tuple, used to select a subset of one-dimensional items in the shape
###### e.g.
import numpy as np
x = np.arange(9).reshape(1,3,3)
print ('array x: ')
print (x)
y = np.squeeze(x)
print ('array y: ')
print (y)
print ('array x and y Shape of:')
print (x.shape, y.shape)
### output:
### Array x:
### [[[0 1 2]
###   [3 4 5]
###   [6 7 8]]]
### Array y:
### [[0 1 2]
###  [3 4 5]
###  [6 7 8]]
### Shape of arrays x and y:
### (1, 3, 3) (3, 3)

## 8.4 connection array

### 8.4.1 numpy.concatenate

numpy.concatenate Function to connect two or more arrays of the same shape along the specified axis.

numpy.concatenate((a1, a2, ...), axis)
### a1, a2,...: array of the same type
### Axis: the axis along which the array is connected. The default is 0
###### e.g.
import numpy as np
a = np.array([[1,2],[3,4]])
print ('First array:')
print (a)
b = np.array([[5,6],[7,8]])
print ('Second array:')
print (b)
# Two arrays have the same dimension
print ('Connect two arrays along axis 0:')
print (np.concatenate((a,b)))
print ('Connect two arrays along axis 1:')
print (np.concatenate((a,b),axis = 1))
### output:
### First array:
### [[1 2]
###  [3 4]]
### Second array:
### [[5 6]
###  [7 8]]
### Connect two arrays along axis 0:
### [[1 2]
###  [3 4]
###  [5 6]
###  [7 8]]
### Connect two arrays along axis 1:
### [[1 2 5 6]
###  [3 4 7 8]]

### 8.4.2 numpy.stack

numpy.stack Function to connect an array sequence along a new axis.

numpy.stack(arrays, axis)
### arrays: array sequence of the same shape
### Axis: returns the axis in the array, and the input array is stacked along it
###### e.g.
import numpy as np
a = np.array([[1,2],[3,4]])
print ('First array:')
print (a)
b = np.array([[5,6],[7,8]])
print ('Second array:')
print (b)
print ('Stack two arrays along axis 0:')
print (np.stack((a,b),0))
print ('Stack two arrays along axis 1:')
print (np.stack((a,b),1))
### output:
### First array:
### [[1 2]
###  [3 4]]
### Second array:
### [[5 6]
###  [7 8]]
### Stack two arrays along axis 0:
### [[[1 2]
###   [3 4]]
###
###  [[5 6]
###   [7 8]]]
### Stack two arrays along axis 1:
### [[[1 2]
###   [5 6]]
###
###  [[3 4]
###   [7 8]]]

### 8.4.3 numpy.hstack

numpy.hstack Yes numpy.stack Function, which generates arrays by stacking horizontally.

import numpy as np
a = np.array([[1,2],[3,4]])
print ('First array:')
print (a)
b = np.array([[5,6],[7,8]])
print ('Second array:')
print (b)
print ('Horizontal stacking:')
c = np.hstack((a,b))
print (c)
### output:
### First array:
### [[1 2]
###  [3 4]]
### Second array:
### [[5 6]
###  [7 8]]
### Horizontal stacking:
### [[1 2 5 6]
###  [3 4 7 8]]

### 8.4.4 numpy.vstack

numpy.vstack Yes numpy.stack Function, which generates arrays by stacking vertically.

import numpy as np
a = np.array([[1,2],[3,4]])
print ('First array:')
print (a)
b = np.array([[5,6],[7,8]])
print ('Second array:')
print (b)
print ('Vertical stacking:')
c = np.vstack((a,b))
print (c)
### output:
### First array:
### [[1 2]
###  [3 4]]
### Second array:
### [[5 6]
###  [7 8]]
### Vertical stacking:
### [[1 2]
###  [3 4]
###  [5 6]
###  [7 8]]

## 8.5 split array

### 8.5.1 numpy.split

numpy.split Function splits an array into subarrays along a specific axis.

numpy.split(ary, indices_or_sections, axis)
### ary: divided array
### indices_or_sections: if it is an integer, the number is used to average segmentation. If it is an array, it is the position along the axis (left open right closed)
### axis: along which dimension is the tangent direction. The default value is 0, horizontal segmentation. At 1, longitudinal segmentation
###### e.g.
import numpy as np
a = np.arange(9)
print ('First array:')
print (a)
print ('Divide the array into three equal sized subarrays:')
b = np.split(a,3)
print (b)
print ('Divide the position indicated by the array in the one-dimensional array:')
b = np.split(a,[4,7])
print (b)
### output:
### First array:
### [0 1 2 3 4 5 6 7 8]
### Divide the array into three equal sized subarrays:
### [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]
### Divide the position indicated by the array in the one-dimensional array:
### [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

### 8.5.2 numpy.hsplit

numpy.hsplit The split() function splits an array horizontally by specifying the number of arrays of the same shape to return.

import numpy as np
harr = np.floor(10 * np.random.random((2, 6)))
print ('primary array: ')
print(harr)
print ('After splitting:')
print(np.hsplit(harr, 3))
### output:
### Original array:
### [[4. 7. 6. 3. 2. 6.]
###  [6. 3. 6. 7. 9. 7.]]
### After splitting:
### [array([[4., 7.],
###        [6., 3.]]), array([[6., 3.],
###        [6., 7.]]), array([[2., 6.],
###        [9., 7.]])]

### 8.5.3 numpy.vsplit

numpy.vsplit Split along the vertical axis in the same way as hsplit.

import numpy as np
a = np.arange(16).reshape(4,4)
print ('First array:')
print (a)
print ('Vertical split:')
b = np.vsplit(a,2)
print (b)
### output:
### First array:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]
###  [12 13 14 15]]
### Vertical split:
### [array([[0, 1, 2, 3],
###        [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
###        [12, 13, 14, 15]])]

## 8.6 addition and deletion of array elements

### 8.6.1 numpy.resize

numpy.resize Function returns a new array of the specified size. If the new array size is larger than the original size, a copy of the elements in the original array is included.

numpy.resize(arr, shape)
### arr: array to modify size
### Shape: returns the new shape of the array
###### e.g.
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print ('First array:')
print (a)
print ('Shape of the first array:')
print (a.shape)
b = np.resize(a, (3,2))
print ('Second array:')
print (b)
print ('Shape of the second array:')
print (b.shape)
# Note that the first line of a is repeated in b because the size is larger
print ('Modify the size of the second array:')
b = np.resize(a,(3,3))
print (b)
### output:
### First array:
### [[1 2 3]
###  [4 5 6]]
### Shape of the first array:
### (2, 3)
### Second array:
### [[1 2]
###  [3 4]
###  [5 6]]
### Shape of the second array:
### (3, 2)
### Modify the size of the second array:
### [[1 2 3]
###  [4 5 6]
###  [1 2 3]]

### 8.6.2 numpy.append

numpy.append Function to add a value at the end of an array. The append operation allocates the entire array and copies the original array to the new array. In addition, the dimensions of the input array must match or ValueError will be generated.
The append function always returns a one-dimensional array.

numpy.append(arr, values, axis=None)
### arr: input array
### values: to add a value to the arr, it needs to be the same as the arr shape (except for the axis to be added)
### Axis: the default is None. When axis has no definition, it is a horizontal addition, and the return is always a one-dimensional array! When axis is defined, it is 0 and 1 respectively. When axis is defined, it is 0 and 1 respectively (the number of columns should be the same). When axis is 1, the array is added to the right (the number of rows should be the same)
###### e.g.
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print ('First array:')
print (a)
print ('To add elements to an array:')
print (np.append(a, [7,8,9]))
print ('Add element along axis 0:')
print (np.append(a, [[7,8,9]],axis = 0))
print ('Add elements along axis 1:')
print (np.append(a, [[5,5,5],[7,8,9]],axis = 1))
### output:
### First array:
### [[1 2 3]
###  [4 5 6]]
### To add elements to an array:
### [1 2 3 4 5 6 7 8 9]
### Add element along axis 0:
### [[1 2 3]
###  [4 5 6]
###  [7 8 9]]
### Add elements along axis 1:
### [[1 2 3 5 5 5]
###  [4 5 6 7 8 9]]

### 8.6.3 numpy.insert

numpy.insert Function inserts a value in the input array along the given axis before the given index.
If the type of the value is converted to be inserted, it is different from the input array. If the insert is not in place, the function returns a new array. In addition, if no axis is provided, the input array is expanded.

numpy.insert(arr, obj, values, axis)
### arr: input array
### obj: index to insert value before
### Values: values to insert
### Axis: along the axis it inserts, if not provided, the input array will be expanded
###### e.g.
import numpy as np
a = np.array([[1,2],[3,4],[5,6]])
print ('First array:')
print (a)
print ('Not delivered Axis Parameters. The input array is expanded before insertion.')
print (np.insert(a,3,[11,12]))
print ('Passed on Axis Parameters. The value array will be broadcast to match the input array.')
print (np.insert(a,1,[11],axis = 0))
print (np.insert(a,1,11,axis = 1))
### output:
### First array:
### [[1 2]
###  [3 4]
###  [5 6]]
### Axis parameter was not passed. The input array is expanded before insertion.
### [ 1  2  3 11 12  4  5  6]
### Axis parameter passed. The value array will be broadcast to match the input array.
### [[ 1  2]
###  [11 11]
###  [ 3  4]
###  [ 5  6]]
### [[ 1 11  2]
###  [ 3 11  4]
###  [ 5 11  6]]

### 8.6.4 numpy.delete

numpy.delete Function to remove a new array from the input array. As in the case of the insert() function, if no axis parameter is provided, the input array expands.

Numpy.delete(arr, obj, axis)
### arr: input array
### obj: can be sliced, integer or integer array, indicating the sub array to be removed from the input array
### Axis: delete the axis to the sub array along it. If not provided, the input array will be expanded
###### e.g.
import numpy as np
a = np.arange(12).reshape(3,4)
print ('First array:')
print (a)
print ('Not delivered Axis Parameters. The input array is expanded before insertion.')
print (np.delete(a,5))
print ('Delete the second column:')
print (np.delete(a,1,axis = 1))
print ('Slice containing the substitution value removed from the array:')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print (np.delete(a, np.s_[::2]))
### output:
### First array:
### [[ 0  1  2  3]
###  [ 4  5  6  7]
###  [ 8  9 10 11]]
### Axis parameter was not passed. The input array is expanded before insertion.
### [ 0  1  2  3  4  6  7  8  9 10 11]
### Delete the second column:
### [[ 0  2  3]
###  [ 4  6  7]
###  [ 8 10 11]]
### Slice containing the substitution value removed from the array:
### [ 2  4  6  8 10]

### 8.6.5 numpy.unique

numpy.unique Function to remove duplicate elements from an array.

numpy.unique(arr, return_index, return_inverse, return_counts)
### arr: input array, if it is not a one-dimensional array, it will expand
### return_index: if true, returns the location (subscript) of the new list element in the old list, and stores it as a list
### return_inverse: if true, returns the location (subscript) of the old list element in the new list and stores it as a list
### return_ Count: if true, returns the number of occurrences of elements in the de duplicated array in the original array
###### e.g.
import numpy as np
a = np.array([5,2,6,2,7,5,6,8,2,9])
print ('First array:')
print (a)
print ('De duplicate value of the first array:')
u = np.unique(a)
print (u)
print ('Index array of de duplicated array:')
u,indices = np.unique(a, return_index = True)
print (indices)
print ('We can see the value corresponding to each subscript of the original array:')
print (a)
print ('Subscript of de duplication array:')
u,indices = np.unique(a,return_inverse = True)
print (u)
print ('The subscript is:')
print (indices)
print ('Use the subscript to reconstruct the original array:')
print (u[indices])
print ('Returns the number of repetitions of the de duplicated elements:')
u,indices = np.unique(a,return_counts = True)
print (u)
print (indices)
### output:
### First array:
### [5 2 6 2 7 5 6 8 2 9]
### De duplicate value of the first array:
### [2 5 6 7 8 9]
### Index array of de duplicated array:
### [1 0 2 4 7 9]
### We can see the value corresponding to each subscript of the original array:
### [5 2 6 2 7 5 6 8 2 9]
### Subscript of de duplication array:
### [2 5 6 7 8 9]
### The subscript is:
### [1 0 2 0 3 1 2 4 0 5]
### Use the subscript to reconstruct the original array:
### [5 2 6 2 7 5 6 8 2 9]
### Returns the number of repetitions of the de duplicated elements:
### [2 5 6 7 8 9]
### [3 2 2 1 1 1]

# 9 NumPy bit operation

Binary operation, less use, check when necessary link Just.

# 10 Numpy common functions

## 10.1 string function

import numpy as np
print ('Connect two strings:')
print ('Connection example:')
print (np.char.add(['hello', 'hi'],[' abc', ' xyz']))
### output
### Connect two strings:
### ['hello xyz']
### Connection example:
### ['hello abc' 'hi xyz']

2 numpy.char.multiply()

import numpy as np
print (np.char.multiply('Runoob ',3))
### output
### Runoob Runoob Runoob

3 numpy.char.center()

import numpy as np
# np.char.center(str , width,fillchar) :
# str: string, width: length, fillchar: fill character
print (np.char.center('Runoob', 20,fillchar = '*'))
### output
### *******Runoob*******

4 numpy.char.capitalize()

import numpy as np
print (np.char.capitalize('runoob'))
### output
### Runoob

5 numpy.char.title()
numpy.char.title The () function converts the first letter of each word of a string to uppercase.

import numpy as np
print (np.char.title('i like runoob'))
### output
### I Like Runoob

6 numpy.char.lower() & numpy.char.upper()
numpy.char.lower The () function converts each element of the array to lowercase. It calls for each element str.lower .
numpy.char.upper The () function converts each element of the array to uppercase. It calls for each element str.upper .

import numpy as np
#Operation array
# Operation string
print (np.char.lower('RUNOOB'))
#Operation array
# Operation string
print (np.char.upper('runoob'))
### output
### runoob
### RUNOOB

7 numpy.char.split()
numpy.char.split() splits the string by specifying a separator and returns an array. By default, the separator is a space.

import numpy as np
# Separator defaults to space
print (np.char.split ('i like runoob?'))
# The separator is
print (np.char.split ('www.runoob.com', sep = '.'))
### output
### ['i', 'like', 'runoob?']
### ['www', 'runoob', 'com']

8 numpy.char.splitlines()
numpy.char.splitlines The () function splits a string with a line break as a separator and returns an array.

import numpy as np
# Line break \ n
print (np.char.splitlines('i\nlike runoob?'))
print (np.char.splitlines('i\rlike runoob?'))
### \n. "\ r \ Nall can be used as line breaks.".

9 numpy.char.strip()
numpy.char.strip The () function removes specific characters at the beginning or end.

import numpy as np
# Remove a character at the beginning and end of a string
print (np.char.strip('ashok arunooba','a'))
# Remove a character at the beginning and end of an array element
### output
### shok arunoob
### ['runoob' 'dmin' 'jav']

10 numpy.char.join()
numpy.char.join The () function connects elements or strings in an array by specifying a separator

import numpy as np
# Operation string
print (np.char.join(':','runoob'))
# Specifying multiple delimiters to manipulate array elements
### output
### r:u:n:o:o:b
### ['r:u:n:o:o:b' 'g-o-o-g-l-e']

11 numpy.char.replace()
numpy.char.replace The () function replaces all substrings in a string with the new string.

import numpy as np
print (np.char.replace ('i like runoob', 'oo', 'cc'))
### output
### i like runccb

12 numpy.char.encode()
numpy.char.encode The () function calls each element in the array str.encode Function. The default encoding is utf-8, and you can use the codec in the standard Python library.

import numpy as np
a = np.char.encode('runoob', 'cp500')
print (a)
### output
### b'\x99\xa4\x95\x96\x96\x82'

13 numpy.char.decode()
numpy.char.decode() function to code elements str.decode() decoding.

import numpy as np
a = np.char.encode('runoob', 'cp500')
print (a)
print (np.char.decode(a,'cp500'))
### output
### b'\x99\xa4\x95\x96\x96\x82'
### runoob

## 10.2 mathematical functions

Trigonometric function
NumPy provides standard trigonometric functions: sin(), cos(), tan().

import numpy as np
a = np.array([0,30,45,60,90])
print ('Sine value of different angles:')
# Convert to radians by multiplying pi/180
print (np.sin(a*np.pi/180))
print ('Cosine value of angle in array:')
print (np.cos(a*np.pi/180))
print ('Tangent value of angle in array:')
print (np.tan(a*np.pi/180))
### output
### Sine value of different angles:
### [0.         0.5        0.70710678 0.8660254  1.        ]
### Cosine value of angle in array:
### [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
###  6.12323400e-17]
### Tangent value of angle in array:
### [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
###  1.63312394e+16]

arcsin, arccos, and arctan functions return the inverse trigonometric functions of sin, cos, and tan for a given angle. The results of these functions can be obtained by numpy.degrees The () function converts radians to angles.

import numpy as np
a = np.array([0,30,45,60,90])
print ('Array with sine:'); sin = np.sin(a*np.pi/180); print (sin)
print ('Calculates the inverse sine of the angle, with the return value in radians:'); inv = np.arcsin(sin); print (inv)
print ('Check the result by converting it to angle system:'); print (np.degrees(inv)); print ('\n')
print ('arccos and arctan The function behaves similarly:'); cos = np.cos(a*np.pi/180); print (cos)
print ('Arccosine:'); inv = np.arccos(cos); print (inv)
print ('Angle system unit:'); print (np.degrees(inv))
print ('tan Function:'); tan = np.tan(a*np.pi/180); print (tan)
print ('Arctangent:'); inv = np.arctan(tan); print (inv)
print ('Angle system unit:');print (np.degrees(inv))
### output:
### Array with sine:
### [0.         0.5        0.70710678 0.8660254  1.        ]
### Calculates the inverse sine of the angle, with the return value in radians:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### Check the result by converting it to angle system:
### [ 0. 30. 45. 60. 90.]
### arccos and arctan functions behave similarly:
### [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
###  6.12323400e-17]
### Arccosine:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### Angle system unit:
### [ 0. 30. 45. 60. 90.]
### tan function:
### [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
###  1.63312394e+16]
### Arctangent:
### [0.         0.52359878 0.78539816 1.04719755 1.57079633]
### Angle system unit:
### [ 0. 30. 45. 60. 90.]

2 rounding function

numpy.around(a,decimals)
### a: Array
### decimals: number of decimal places to round. The default value is 0. If negative, the integer is rounded to the left of the decimal point
###### example
import numpy as np
a = np.array([1.0,5.55,  123,  0.567,  25.532])
print  ('Original array:')
print (a)
print ('After rounding:')
print (np.around(a))
print (np.around(a, decimals =  1))
print (np.around(a, decimals =  -1))
### output
### Original array:
### [  1.      5.55  123.      0.567  25.532]
### After rounding:
### [  1.   6. 123.   1.  26.]
### [  1.    5.6 123.    0.6  25.5]
### [  0.  10. 120.   0.  30.]

3 numpy.floor()
numpy.floor() returns the largest integer less than or equal to the specified expression, which is rounded down.

import numpy as np
a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])
print ('Array provided:')
print (a)
print ('Modified array:')
print (np.floor(a))
### output
### Array provided:
### [-1.7  1.5 -0.2  0.6 10. ]
### Modified array:
### [-2.  1. -1.  0. 10.]

4 numpy.ceil()
numpy.ceil() returns the smallest integer greater than or equal to the specified expression, which is rounded up.

import numpy as np
a = np.array([-1.7,  1.5,  -0.2,  0.6,  10])
print  ('Array provided:')
print (a)
print ('Modified array:')
print (np.ceil(a))
### output
### Array provided:
### [-1.7  1.5 -0.2  0.6 10. ]
### Modified array:
### [-1.  2. -0.  1. 10.]

## 10.3 arithmetic functions

1. Basic addition, subtraction, multiplication and division functions: add(), subtract(), multiply(), and divide().

import numpy as np
a = np.arange(9, dtype = np.float_).reshape(3,3)
print ('First array:'); print (a)
print ('Second array:'); b = np.array([10,10,10])  print (b)
print ('Subtract two arrays:'); print (np.subtract(a,b))
print ('Multiply two arrays:'); print (np.multiply(a,b))
print ('Divide two arrays:'); print (np.divide(a,b))
### output
### First array:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### Second array:
### [10 10 10]
### [[10. 11. 12.]
###  [13. 14. 15.]
###  [16. 17. 18.]]
### Subtract two arrays:
### [[-10.  -9.  -8.]
### [ -7.  -6.  -5.]
###  [ -4.  -3.  -2.]]
### Multiply two arrays:
### [[ 0. 10. 20.]
###  [30. 40. 50.]
###  [60. 70. 80.]]
### Divide two arrays:
### [[0.  0.1 0.2]
###  [0.3 0.4 0.5]
###  [0.6 0.7 0.8]]

2 numpy.reciprocal()
numpy.reciprocal() function returns the reciprocal of each element of the parameter. For example, the reciprocal of 1 / 4 is 4 / 1.

import numpy as np
a = np.array([0.25,  1.33,  1,  100])
print ('Our array is:'); print (a)
print ('call reciprocal Function:'); print (np.reciprocal(a))
### output:
### Our array is:
### [  0.25   1.33   1.   100.  ]
### Call the corrective function:
### [4.        0.7518797 1.        0.01     ]

3 numpy.power()
numpy.power The () function takes the element in the first input array as the base number and calculates its power with the corresponding element in the second input array.

import numpy as np
a = np.array([10,100,1000])
print ('Our array is;'); print (a)
print ('call power Function:'); print (np.power(a,2))
print ('Second array:'); b = np.array([1,2,3]); print (b)
print ('Call again power Function:'); print (np.power(a,b))
### output:
### Our array is;
### [  10  100 1000]
### Call the power function:
### [    100   10000 1000000]
### Second array:
### [1 2 3]
### Call the power function again:
### [        10      10000 1000000000]

4 numpy.mod()
numpy.mod() calculates the remainder after dividing the corresponding elements in the input array. Functions numpy.remainder() produces the same result.

import numpy as np
a = np.array([10,20,30]); b = np.array([3,5,7])
print ('First array:'); print (a)
print ('Second array:'); print (b)
print ('call mod() Function:'); print (np.mod(a,b))
print ('call remainder() Function:'); print (np.remainder(a,b))
### output:
### First array:
### [10 20 30]
### Second array:
### [3 5 7]
### Call mod() function:
### [1 0 2]
### Call the remainder() function:
### [1 0 2]

## 10.4 statistical functions

One numpy.amin () and numpy.amax()
numpy.amin() is used to calculate the minimum value of elements in the array along the specified axis; numpy.amax() is used to calculate the maximum value of elements in the array along the specified axis.

import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print ('Our array is:'); print (a)
print ('call amin() Function:'); print (np.amin(a,1))
print ('Call again amin() Function:'); print (np.amin(a,0))
print ('call amax() Function:'); print (np.amax(a))
print ('Call again amax() Function:'); print (np.amax(a, axis =  0))
### output:
### Our array is:
### [[3 7 5]
###  [8 4 3]
###  [2 4 9]]
### Call the amin() function:
### [3 3 2]
### Call the amin() function again:
### [2 4 3]
### Call amax() function:
### 9
### Call the amax() function again:
### [8 7 9]

2 numpy.ptp()
numpy.ptp() function calculates the difference between the maximum value and the minimum value of elements in the array (max - min).

import numpy as np
a = np.array([[3,7,5],[8,4,3],[2,4,9]])
print ('Our array is:'); print (a)
print ('call ptp() Function:'); print (np.ptp(a))
print ('Call along axis 1 ptp() Function:'); print (np.ptp(a, axis =  1))
print ('Call along axis 0 ptp() Function:'); print (np.ptp(a, axis =  0))
### output:
### Our array is:
### [[3 7 5]
###  [8 4 3]
###  [2 4 9]]
### Call the ptp() function:
### 7
### Call ptp() function along axis 1:
### [4 5 7]
### Call ptp() function along axis 0:
### [6 3 6]

3 numpy.percentile()
Percentiles are measures used in statistics that represent the percentage of observations less than this value. function numpy.percentile() accepts the following parameters.

numpy.percentile(a, q, axis)
### a: Input array
### q: Percentile to calculate, between 0 and 100
### Axis: the axis along which the percentile is calculated
###### example
import numpy as np
a = np.array([[10, 7, 4], [3, 2, 1]])
print ('Our array is:'); print (a); print ('call percentile() Function:')
# 50% quantile is the median after sorting in a
print (np.percentile(a, 50))
# axis is 0, find on column
print (np.percentile(a, 50, axis=0))
# axis is 1, which is on the horizontal line
print (np.percentile(a, 50, axis=1))
# Keep dimensions the same
print (np.percentile(a, 50, axis=1, keepdims=True))
### output:
### Our array is:
### [[10  7  4]
###  [ 3  2  1]]
### Call the percentile() function:
### 3.5
### [6.5 4.5 2.5]
### [7. 2.]
### [[7.]
###  [2.]]

4 numpy.median()
numpy.median() function is used to calculate the median (median) of elements in array a

import numpy as np
a = np.array([[30,65,70],[80,95,10],[50,90,60]])
print ('Our array is:'); print (a)
print ('call median() Function:'); print (np.median(a))
print ('Call along axis 0 median() Function:'); print (np.median(a, axis =  0))
print ('Call along axis 1 median() Function:'); print (np.median(a, axis =  1))
### output:
### Our array is:
### [[30 65 70]
###  [80 95 10]
###  [50 90 60]]
### Call the media() function:
### 65.0
### Call the median() function along axis 0:
### [50. 90. 60.]
### Call the media() function along axis 1:
### [65. 80. 60.]

5 numpy.mean() and numpy.average()
numpy.mean The () function returns the arithmetic mean of the elements in the array. If an axis is provided, it is calculated along it. The arithmetic mean is the sum of the elements along the axis divided by the number of elements.
numpy.average The () function calculates the weighted average of the elements in the array according to the respective weights given in another array. This function accepts an axis parameter. If no axis is specified, the array is expanded. The weighted average is the sum of the values multiplied by the corresponding weights, then the sum is the total value, and then divided by the total number of units. Consider the array [1,2,3,4] and the corresponding weight [4,3,2,1], and calculate the weighted average by adding the product of the corresponding elements and dividing the sum by the sum of the weights.

import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print ('Our array is:'); print (a)
print ('call mean() Function:'); print (np.mean(a))
print ('Call along axis 0 mean() Function:'); print (np.mean(a, axis =  0))
print ('Call along axis 1 mean() Function:'); print (np.mean(a, axis =  1))
### output:
### Our array is:
### [[1 2 3]
###  [3 4 5]
###  [4 5 6]]
### Call the mean() function:
### 3.6666666666666665
### Call the mean() function along axis 0:
### [2.66666667 3.66666667 4.66666667]
### Call the mean() function along axis 1:
### [2. 4. 5.]
###### ---------------------------------------------------------------------------
import numpy as np
a = np.array([1,2,3,4]); print ('Our array is:'); print (a)
print ('call average() Function:'); print (np.average(a)) # When no weight is specified, it is equivalent to mean function
wts = np.array([4,3,2,1])
print ('Call again average() Function:'); print (np.average(a,weights = wts))
# If the returned parameter is set to true, the sum of the weights is returned
print ('Sum of weights:');print (np.average([1,2,3,4],weights =  [4,3,2,1], returned=True))
### output:
### Our array is:
### [1 2 3 4]
### Call the average() function:
### 2.5
### Call the average() function again:
### 2.0
### Sum of weights:
### (2.0, 10.0)
###### ---------------------------------------------------------------------------
### In a multidimensional array, you can specify the axis to use for the calculation
import numpy as np
a = np.arange(6).reshape(3,2); print ('Our array is:'); print (a)
print ('Modified array:');wt = np.array([3,5]);print (np.average(a,axis =1,weights= wt))
print ('Modified array:');print (np.average(a, axis = 1, weights = wt, returned =  True))
### output:
### Our array is:
### [[0 1]
###  [2 3]
###  [4 5]]
### Modified array:
### [0.625 2.625 4.625]
### Modified array:
### (array([0.625, 2.625, 4.625]), array([8., 8., 8.]))

6 standard deviation and variance

import numpy as np; print (np.std([1,2,3,4])) # standard deviation
print (np.var([1,2,3,4])) # variance
### output:
### 1.1180339887498949
### 1.25

## 10.5 sorting and conditional swiping function

One numpy.sort (): numpy.sort The () function returns a sorted copy of the input array.

numpy.sort(a, axis, kind, order)
### axis: axis=0 sort by column, axis=1 sort by row
### kind: default is' quicksort '
### order: if the array contains fields, the fields to sort
###### example
import numpy as np

a = np.array([[3,7],[9,1]])
print ('Our array is:')
print (a)
print ('call sort() Function:'); print (np.sort(a))
print ('Sort by column:'); print (np.sort(a, axis =  0))
# Sorting fields in the sort function
dt = np.dtype([('name',  'S10'),('age',  int)])
a = np.array([("raju",21),("anil",25),("ravi",  17),  ("amar",27)], dtype = dt)
print ('Our array is:'); print (a)
print ('Press name Sort:'); print (np.sort(a, order =  'name'))
### output:
### Our array is:
### [[3 7]
###  [9 1]]
### Call the sort() function:
### [[3 7]
###  [1 9]]
### Sort by column:
### [[3 1]
###  [9 7]]
### Our array is:
### [(b'raju', 21) (b'anil', 25) (b'ravi', 17) (b'amar', 27)]
### Sort by name:
### [(b'amar', 27) (b'anil', 25) (b'raju', 21) (b'ravi', 17)]

Two numpy.argsort(): numpy.argsort() function returns the index value of array value from small to large.

import numpy as np
x = np.array([3,  1,  2])
print ('Our array is:'); print (x)
print ('Yes x call argsort() Function:'); y = np.argsort(x); print (y)
print ('Reconstruct the original array in the sorted order:'); print (x[y])
print ('Use the loop to reconstruct the original array:')
for i in y:
print (x[i], end=" ")
### output:
### Our array is:
### [3 1 2]
### Call the argsort() function on x:
### [1 2 0]
### Reconstruct the original array in the sorted order:
### [1 2 3]
### Using loop to reconstruct the original array
### 1 2 3

3 numpy.lexsort()
numpy.lexsort() is used to sort multiple sequences. Think of it as sorting in pairs of spreadsheets. Each column represents a sequence. When sorting, the later columns are given priority.

import numpy as np
nm =  ('raju','anil','ravi','amar'); dv =  ('f.y.',  's.y.',  's.y.',  'f.y.')
ind = np.lexsort((dv,nm)); print ('call lexsort() Function:'); print (ind)
print ('Use this index to get the sorted data:'); print ([nm[i]  +  ", "  + dv[i]  for i in ind])
### output
### Call the lexport() function:
### [3 1 0 2]
### Use this index to get the sorted data:
### ['amar, f.y.', 'anil, s.y.', 'raju, f.y.', 'ravi, s.y.']

4
msort(a): the array is sorted by the first axis, and the sorted array copy is returned. np.msort(a) Equal to np.sort(a, axis=0).
sort_complex(a): sort the complex numbers in the order of real parts first and virtual parts later.
partition(a, kth[, axis, kind, order]): specify a number to partition the array.
argpartition(a, kth[, axis, kind, order]): the array can be partitioned along the specified axis by the algorithm specified by the keyword kind.

Five numpy.argmax () and numpy.argmin()
numpy.argmax() and numpy.argmin The () function returns the index of the maximum and minimum elements along the given axis, respectively.

import numpy as np
a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print  ('Our array is:'); print (a)
print ('call argmax() Function:'); print (np.argmax(a))
print ('Expand array:'); print (a.flatten())
print ('Maximum index along axis 0:'); maxindex = np.argmax(a, axis =  0); print (maxindex)
print ('Maximum index along axis 1:'); maxindex = np.argmax(a, axis =  1); print (maxindex)
print ('call argmin() Function:'); minindex = np.argmin(a); print (minindex)
print ('Expand the minimum value in the array:'); print (a.flatten()[minindex])
print ('Minimum index along axis 0:'); minindex = np.argmin(a, axis =  0); print (minindex)
print ('Minimum index along axis 1:'); minindex = np.argmin(a, axis =  1); print (minindex)
### output:
### Our array is:
### [[30 40 70]
###  [80 20 10]
###  [50 90 60]]
### Call the argmax() function:
### 7
### Expand array:
### [30 40 70 80 20 10 50 90 60]
### Maximum index along axis 0:
### [1 2 0]
### Maximum index along axis 1:
### [2 0 1]
### Call the argmin() function:
### 5
### Expand the minimum value in the array:
### 10
### Minimum index along axis 0:
### [0 1 1]
### Minimum index along axis 1:
### [0 2 0]

Six numpy.nonzero(): numpy.nonzero The () function returns the index of a non-zero element in the input array.

import numpy as np
a = np.array([[30,40,0],[0,20,10],[50,0,60]]); print ('Our array is:'); print (a)
print ('call nonzero() Function:'); print (np.nonzero (a))
### output:
### Our array is:
### [[30 40  0]
###  [ 0 20 10]
###  [50  0 60]]
### Call the nonzero() function:
### (array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))

7 numpy.where()
numpy.where The () function returns the index of the element in the input array that meets the given criteria.

import numpy as np
x = np.arange(9.).reshape(3,  3); print ('Our array is:'); print (x)
print ( 'Index of elements greater than 3:'); y = np.where(x >  3); print (y)
print ('Use these indexes to get elements that meet the criteria:'); print (x[y])
### output:
### Our array is:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### Index of elements greater than 3:
### (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
### Use these indexes to get elements that meet the criteria:
### [4. 5. 6. 7. 8.]

8 numpy.extract()
numpy.extract The () function extracts elements from an array based on a condition and returns the elements with full conditions.

import numpy as np
x = np.arange(9.).reshape(3,  3); print ('Our array is:'); print (x)
# Define conditions, select even elements
condition = np.mod(x,2)  ==  0; print ('Conditional values by element:'); print (condition)
print ('Use condition extraction element:'); print (np.extract(condition, x))
### output:
### Our array is:
### [[0. 1. 2.]
###  [3. 4. 5.]
###  [6. 7. 8.]]
### Conditional values by element:
### [[ True False  True]
###  [False  True False]
###  [ True False  True]]
### Use condition extraction element:
### [0. 2. 4. 6. 8.]

# 11 NumPy copy and view (mainly judge whether ID() is the same)

## 11.1 no duplication

A simple assignment does not create a copy of the array object. Instead, it uses the same id() of the original array to access it. id() returns the general identifier of the Python object, similar to a pointer in C. In addition, any changes in one array are reflected in the other. For example, changing the shape of one array can also change the shape of another array.

import numpy as np
a = np.arange(6)
print ('Our array is:'); print (a)
print ('call id() Function:'); print (id(a))
print ('a Assign to b: '); b = a; print (b)
print ('b Have the same id(): '); print (id(b))
print ('modify b Shape of:'); b.shape =  3,2; print (b)
print ('a The shape of is also modified:'); print (a)
### output:
### Our array is:
### [0 1 2 3 4 5]
### Call the id() function:
### 4349302224
### a assigned to b:
### [0 1 2 3 4 5]
### b has the same id():
### 4349302224
### Modify the shape of b:
### [[0 1]
###  [2 3]
###  [4 5]]
### a's shape has also been modified:
### [[0 1]
###  [2 3]
###  [4 5]]

## 11.2 ndarray.view() and ndarray.copy()

The above two functions work similarly. a=np.array([1, 2, 3, 4, 5, 6]); b=a.copy(); b=a.view()

# 12 NumPy matrix library (Matrix)

## 12.1 matlib.empty()

matlib.empty() function returns a new matrix

numpy.matlib.empty(shape, dtype, order)
### Shape: an integer or integer tuple defining the shape of a new matrix
### Dtype: optional, data type
### order: C (row order first) or F (column order first)
###### example
import numpy.matlib
import numpy as np
print (np.matlib.empty((2,2)))
# Fill with random data
### output:
### [[-1.49166815e-154 -1.49166815e-154]
###  [ 2.17371491e-313  2.52720790e-212]]

## 12.2 numpy.matlib.zeros() and numpy.matlib.ones()

numpy.matlib.zeros The () function creates a matrix filled with 0.
numpy.matlib.ones The () function creates a matrix filled with 1.

import numpy.matlib
import numpy as np
print (np.matlib.zeros((2,2)))
print (np.matlib.ones((2,2)))
### output:
### [[0. 0.]
###  [0. 0.]]
### [[1. 1.]
###  [1. 1.]]

## 12.3 numpy.matlib.eye()

numpy.matlib.eye The () function returns a matrix with a diagonal element of 1 and zero other positions.

numpy.matlib.eye(n, M,k, dtype)
### n: Returns the number of rows in the matrix
### M: Returns the number of columns of the matrix, the default is n
### k: Index of diagonal
###### example
import numpy.matlib
import numpy as np
print (np.matlib.eye(n =  3, M =  4, k =  0, dtype =  float))
### output:
### [[1. 0. 0. 0.]
###  [0. 1. 0. 0.]
###  [0. 0. 1. 0.]]

## 12.4 numpy.matlib.identity()

numpy.matlib.identity() function returns the unit matrix of the given size. The unit matrix is a square matrix. The elements on the diagonal (called the main diagonal) from the upper left corner to the lower right corner are all 1, and all of them are 0.

import numpy.matlib
import numpy as np
# Size 5, type bit floating point
print (np.matlib.identity(5, dtype =  float))
### output:
### [[ 1.  0.  0.  0.  0.]
###  [ 0.  1.  0.  0.  0.]
###  [ 0.  0.  1.  0.  0.]
###  [ 0.  0.  0.  1.  0.]
###  [ 0.  0.  0.  0.  1.]]

## 12.5 numpy.matlib.rand()

numpy.matlib.rand The () function creates a matrix of a given size with randomly populated data.

import numpy.matlib
import numpy as np
print (np.matlib.rand(3,3))
### output:
### [[0.23966718 0.16147628 0.14162   ]
###  [0.28379085 0.59934741 0.62985825]
###  [0.99527238 0.11137883 0.41105367]]

## 12.6 Other Functions

import numpy.matlib
import numpy as np
i = np.matrix('1,2;3,4')
print (i)
j = np.asarray(i)
print (j)
k = np.asmatrix (j)
print (k)
### output:
### [[1  2]
###  [3  4]]
### [[1  2]
###  [3  4]]
### [[1  2]
###  [3  4]]

# 13 NumPy linear algebra

## 13.1 numpy.dot()

numpy.dot() For two one-dimensional arrays, the product sum of the subscript elements corresponding to the two arrays is calculated (mathematically referred to as the inner product); for two-dimensional arrays, the matrix product of the two arrays is calculated; for multi-dimensional arrays, the general calculation formula is as follows, that is, each element in the result array is: all the elements in the last one dimension of array A and the elements in the last two digits of array B Sum of product of all elements: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m]).

numpy.dot(a, b, out=None)
### A: ndarray array
### B: array of ndarray
### Out: ndarray, optional, used to save the calculation result of dot()
###### example
import numpy.matlib
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
print(np.dot(a,b))
### output:
### [[37  40]
###  [85  92]]
### Calculation formula: [[1 * 11 + 2 * 13, 1 * 12 + 2 * 14], [3 * 11 + 4 * 13, 3 * 12 + 4 * 14]]

## 13.2 numpy.vdot()

numpy.vdot() function is the dot product of two vectors. If the first parameter is a complex number, its conjugate complex number is used for calculation. If the parameter is a multidimensional array, it will be expanded.

import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[11,12],[13,14]])
# vdot expands array to calculate inner product
print (np.vdot(a,b))
### output:
### 130
### 1*11 + 2*12 + 3*13 + 4*14 = 130

## 13.3 numpy.inner()

numpy.inner The () function returns the vector inner product of a one-dimensional array. For higher dimensions, it returns the product of the sum on the last axis.

import numpy as np
print (np.inner(np.array([1,2,3]),np.array([0,1,0])))
# Equivalent to 1 * 0 + 2 * 1 + 3 * 0
### output:
### 2
###----------------------------------------------------------------------------------
a = np.array([[1,2], [3,4]])
print ('array a: '); print (a)
b = np.array([[11, 12], [13, 14]])
print ('array b: '); print (b)
print ('Inner product:'); print (np.inner(a,b))
### output:
### Array a:
### [[1 2]
###  [3 4]]
### Array b:
### [[11 12]
###  [13 14]]
### Inner product:
### [[35 41]
###  [81 95]]
### Calculation formula:
### 1*11+2*12, 1*13+2*14
### 3*11+4*12, 3*13+4*14

## 13.4 numpy.matmul

numpy.matmul Function returns the matrix product of two arrays. Although it returns the normal product of the two-dimensional array, if the dimension of any parameter is greater than 2, it is regarded as the stack of the matrix existing in the last two indexes and broadcast accordingly.
On the other hand, if any parameter is a one-dimensional array, it is promoted to a matrix by appending 1 to its dimension and is removed after multiplication.

import numpy.matlib
import numpy as np
a = [[1,0],[0,1]]
b = [[4,1],[2,2]]
print (np.matmul(a,b))
a = [[1,0],[0,1]]
b = [1,2]
print (np.matmul(a,b))
print (np.matmul(b,a))
### output:
### [[4  1]
###  [2  2]]
### [1  2]
### [1  2]

## thirteen point five numpy.linalg.det (): Calculation of determinant

numpy.linalg.det() function calculates the determinant of the input matrix.
Determinants are very useful values in linear algebra. It is calculated from the diagonal elements of a square matrix. For a 2 × 2 matrix, it is the difference between the product of the upper left and lower right elements and the product of the other two elements.
In other words, for matrices [[a, b], [c, d], the determinant is calculated as ad BC. The larger square matrix is considered to be a combination of 2 × 2 matrices.

import numpy as np
a = np.array([[1,2], [3,4]])
print (np.linalg.det(a))
b = np.array([[6,1,1], [4, -2, 5], [2,8,7]])
print (b)
print (np.linalg.det(b))
print (6*(-2*7 - 5*8) - 1*(4*7 - 5*2) + 1*(4*8 - -2*2))
### output:
### -2.0
### [[ 6  1  1]
###  [ 4 -2  5]
###  [ 2  8  7]]
### -306.0
### -306

## 13.6 numpy.linalg.solve() and numpy.linalg.inv()

numpy.linalg.solve() function gives the solution of linear equation in matrix form.
numpy.linalg.inv() function calculates the multiplication inverse matrix of the matrix.

import numpy as np
a = np.array([[1,1,1],[0,2,5],[2,5,-1]]); print ('array a: '); print (a)
ainv = np.linalg.inv(a); print ('a Inverse of:'); print (ainv)
print ('matrix b: '); b = np.array([[6],[-4],[27]]); print (b)
print ('calculation: A^(-1)B: '); x = np.linalg.solve(a,b);print (x)
# This is the solution of linear direction x = 5, y = 3, z = -2
### output:
### Array a:
### [[ 1  1  1]
###  [ 0  2  5]
###  [ 2  5 -1]]
### Inverse of a:
### [[ 1.28571429 -0.28571429 -0.14285714]
###  [-0.47619048  0.14285714  0.23809524]
###  [ 0.19047619  0.14285714 -0.0952381 ]]
### Matrix b:
### [[ 6]
###  [-4]
###  [27]]
### Calculation: A^(-1)B:
### [[ 5.]
###  [ 3.]
###  [-2.]]
###### The results can also be obtained by changing the formula: X= np.dot (ainv,b)

# 14 NumPy IO

## 14.1 numpy.save()

numpy.save The () function saves the array to a file with an. npy extension.

import numpy as np
a = np.array([1,2,3,4,5])
# Save to outfile.npy  On file
np.save('outfile.npy',a)
# Save to the outfile2.npy file. If there is no extension. NPY at the end of the file path, the extension will be added automatically
np.save('outfile2',a)
print (b)
### output:
### [1 2 3 4 5]

## 14.2 numpy.savez()

numpy.savez The () function saves multiple arrays to a file with an npz extension.

import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c uses the keyword parameter sin_array
np.savez("runoob.npz", a, b, sin_array = c)
print(r.files) # View array names
print(r["arr_0"]) # Array a
print(r["arr_1"]) # Array b
print(r["sin_array"]) # Array c
### output:
### ['sin_array', 'arr_0', 'arr_1']
### [[1 2 3]
###  [4 5 6]]
### [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
### [0.         0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
###  0.56464247 0.64421769 0.71735609 0.78332691]

The savetxt() function stores data in a simple text file format, and correspondingly uses the loadtext() function to obtain data.

import numpy as np
a=np.arange(0,10,0.5).reshape(4,-1)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # Save as integer instead, separated by commas