# Chapter 1 preliminary knowledge of pandas (list derivation and conditional assignment, anonymous function and map method, zip object and enumerate method, NP basis)

2022-01-30 13:17:23

# Chapter one Preliminary knowledge

## One 、Python Basics ### 1. List derivation and conditional assignment

When generating a sequence of numbers , stay Python It can be written as follows ：

L = []
def my_func(x):
return 2*x
for i in range(5):
L.append(my_func(i))
L
Copy code 
[0, 2, 4, 6, 8]
Copy code 

In fact, we can use the list derivation to simplify the writing method ：[* for i in *]. among , first * For mapping function , Its input is the following i Content of reference , the second * Object representing iteration .

[my_func(i) for i in range(5)]
Copy code 
[0, 2, 4, 6, 8]
Copy code 

List expressions also support multi-level nesting , As the first in the following example for For outer circulation , The second is the inner loop ：

[m+'_'+n for m in ['a', 'b'] for n in ['c', 'd']]
Copy code 
['a_c', 'a_d', 'b_c', 'b_d']
Copy code 

Except for list derivation , Another useful grammar is sugar with if Assignment of selected conditions , In the form of value = a if condition else b

value = 'cat' if 2>1 else 'dog'
value
Copy code 
'cat'
Copy code 

Equivalent to the following expression ：

a, b = 'cat', 'dog'
condition = 2 > 1 #  This is the case True
if condition:
value = a
else:
value = b
Copy code 

Here's an example , More than... In the truncated list 5 The elements of , More than 5 The use of 5 Instead of , Less than 5 Keep the original value ：

L = [1, 2, 3, 4, 5, 6, 7]
[i if i <= 5 else 5 for i in L]
Copy code 
[1, 2, 3, 4, 5, 5, 5]
Copy code 

### 2. Anonymous function and map Method

Some functions are defined with clear and simple mapping relationships , For example, above my_func function , At this time, we can use the method of anonymous function to express ：

my_func = lambda x: 2*x
my_func(3)
Copy code 
6
Copy code 
multi_para_func = lambda a, b: a + b
multi_para_func(1, 2)
Copy code 
3
Copy code 

But the above usage actually violates “ anonymous ” The meaning of , In fact, it is often used in situations where multiple calls are not required , For example, the example in the above list derivation , The user doesn't care about the name of the function , Only care about this mapping relationship ：

[(lambda x: 2*x)(i) for i in range(5)]
Copy code 
[0, 2, 4, 6, 8]
Copy code 

For the anonymous function mapping of the above list derivation ,Python Provided in map Function to complete , What it returns is a map object , Need to pass through list Turn to list ：

list(map(lambda x: 2*x, range(5)))
Copy code 
[0, 2, 4, 6, 8]
Copy code 

For function mapping of multiple input values , You can do this by appending an iteration object ：

list(map(lambda x, y: str(x)+'_'+y, range(5), list('abcde')))
Copy code 
['0_a', '1_b', '2_c', '3_d', '4_e']
Copy code 

### 3. zip Object and the enumerate Method

zip Function can package multiple iteratable objects into an iteratable object composed of a tuple , It returns a zip object , adopt tuple, list You can get the corresponding packaging results ：

L1, L2, L3 = list('abc'), list('def'), list('hij')
list(zip(L1, L2, L3))
Copy code 
[('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]
Copy code 
tuple(zip(L1, L2, L3))
Copy code 
(('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j'))
Copy code 

It is often used in loop iteration zip function ：

for i, j, k in zip(L1, L2, L3):
print(i, j, k)
Copy code 
a d h
b e i
c f j
Copy code 

enumerate It's a special kind of packing , It can bind the traversal sequence number of iterative elements during iteration ：

L = list('abcd')
for index, value in enumerate(L):
print(index, value)
Copy code 
0 a
1 b
2 c
3 d
Copy code 

use zip Objects can also simply implement this function ：

for index, value in zip(range(len(L)), L):
print(index, value)
Copy code 
0 a
1 b
2 c
3 d
Copy code 

When you need to establish a dictionary mapping between two lists , You can use zip object ：

dict(zip(L1, L2))
Copy code 
{'a': 'd', 'b': 'e', 'c': 'f'}
Copy code 

Now that you have the compression function , that Python Also provided * Operators, and zip Joint use to decompress ：

zipped = list(zip(L1, L2, L3))
zipped
Copy code 
[('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]
Copy code 
list(zip(*zipped)) #  The three tuples correspond to the original list
Copy code 
[('a', 'b', 'c'), ('d', 'e', 'f'), ('h', 'i', 'j')]
Copy code 

## Two 、Numpy Basics

### 1. np Array construction

The most common way is through array To construct the ：

import numpy as np
np.array([1,2,3])
Copy code 
array([1, 2, 3])
Copy code 

Here are some ways to generate special arrays ：

【a】 The arithmetic sequence ：np.linspace, np.arange

np.linspace(1,5,11) #  start 、 End （ contain ）、 Number of samples
Copy code 
array([1. , 1.4, 1.8, 2.2, 2.6, 3. , 3.4, 3.8, 4.2, 4.6, 5. ])
Copy code 
np.arange(1,5,2) #  start 、 End （ It doesn't contain ）、 step
Copy code 
array([1, 3])
Copy code 

【b】 Special matrix ：zeros, eye, full

np.zeros((2,3)) #  The incoming tuple represents the size of each dimension
Copy code 
array([[0., 0., 0.],
[0., 0., 0.]])
Copy code 
np.eye(3) # 3*3 The identity matrix of
Copy code 
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Copy code 
np.eye(3, k=1) #  Offset the main diagonal 1 A pseudo identity matrix of units
Copy code 
array([[0., 1., 0.],
[0., 0., 1.],
[0., 0., 0.]])
Copy code 
np.full((2,3), 10) #  Tuple incoming size ,10 Indicates the fill value
Copy code 
array([[10, 10, 10],
[10, 10, 10]])
Copy code 
np.full((2,3), [1,2,3]) #  Fill in the same list for each line
Copy code 
array([[1, 2, 3],
[1, 2, 3]])
Copy code 

【c】 Random matrix ：np.random

The most commonly used random generating function is rand, randn, randint, choice, They represent 0-1 Evenly distributed random arrays 、 Standard normal random array 、 Random integer group and random list sampling ：

np.random.rand(3) #  Generative obedience 0-1 Three random numbers uniformly distributed
Copy code 
array([0.92340835, 0.20019461, 0.40755472])
Copy code 
np.random.rand(3, 3) #  Note that this is not a tuple , Each dimension size is entered separately
Copy code 
array([[0.8012362 , 0.53154881, 0.05858554],
[0.13103034, 0.18108091, 0.30253153],
[0.00528884, 0.99402007, 0.36348797]])
Copy code 

For obedience interval a To b The uniform distribution on can be generated as follows ：

a, b = 5, 15
(b - a) * np.random.rand(3) + a
Copy code 
array([6.59370831, 8.03865138, 9.19172546])
Copy code 

General , You can select existing library functions ：

np.random.uniform(5, 15, 3)
Copy code 
array([11.26499636, 13.12311185,  6.00774156])
Copy code 

randn Generated N(0,I) The standard normal distribution of ：

np.random.randn(3)
Copy code 
array([ 1.87000209,  1.19885561, -0.58802943])
Copy code 
np.random.randn(2, 2)
Copy code 
array([[-1.3642839 , -0.31497567],
[-1.9452492 , -3.17272882]])
Copy code 

For compliance, the variance is $\sigma^2$ The mean for $\mu$ The univariate normal distribution of can be generated as follows ：

sigma, mu = 2.5, 3
mu + np.random.randn(3) * sigma
Copy code 
array([1.56024917, 0.22829486, 7.3764211 ])
Copy code 

alike , You can also choose to generate... From existing functions ：

np.random.normal(3, 2.5, 3)
Copy code 
array([3.53517851, 5.3441269 , 3.51192744])
Copy code 

randint You can specify the minimum and maximum values for generating random integers （ It doesn't contain ） And dimension size ：

low, high, size = 5, 15, (2,2) #  Generate 5 To 14 Random integer of
np.random.randint(low, high, size)
Copy code 
array([[ 5, 12],
[14,  9]])
Copy code 

choice From a given list , Extract results in a certain probability and way , Uniform sampling when probability is not specified , The default sampling method is put back sampling ：

my_list = ['a', 'b', 'c', 'd']
np.random.choice(my_list, 2, replace=False, p=[0.1, 0.7, 0.1 ,0.1])
Copy code 
array(['b', 'a'], dtype='<U1')
Copy code 
np.random.choice(my_list, (3,3))
Copy code 
array([['c', 'b', 'd'],
['d', 'a', 'd'],
['a', 'c', 'd']], dtype='<U1')
Copy code 

When the number of returned elements is the same as the original list , Sampling without putting it back is equivalent to using permutation function , That is to break up the original list ：

np.random.permutation(my_list)
Copy code 
array(['c', 'a', 'd', 'b'], dtype='<U1')
Copy code 

Last , It should be mentioned that random seeds , It can fix the output of random numbers ：

np.random.seed(0)
np.random.rand()
Copy code 
0.5488135039273248
Copy code 
np.random.seed(0)
np.random.rand()
Copy code 
0.5488135039273248
Copy code 

### 2. np Deformation and merging of arrays

【a】 Transposition ：T

np.zeros((2,3)).T
Copy code 
array([[0., 0.],
[0., 0.],
[0., 0.]])
Copy code 

【b】 Merge operation ：r_, c_

For two-dimensional arrays ,r_ and c_ Represents up-down merging and left-right merging respectively ：

np.r_[np.zeros((2,3)),np.zeros((2,3))]
Copy code 
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
Copy code 
np.c_[np.zeros((2,3)),np.zeros((2,3))]
Copy code 
array([[0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0.]])
Copy code 

When merging one-dimensional arrays and two-dimensional arrays , Think of it as a column vector , It can only be used in the case of left and right length matching c_ operation ：

try:
np.r_[np.array([0,0]),np.zeros((2,1))]
except Exception as e:
Err_Msg = e
Err_Msg
Copy code 
ValueError('all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 2 dimension(s)')
Copy code 
np.r_[np.array([0,0]),np.zeros(2)]
Copy code 
array([0., 0., 0., 0.])
Copy code 
np.c_[np.array([0,0]),np.zeros((2,3))]
Copy code 
array([[0., 0., 0., 0.],
[0., 0., 0., 0.]])
Copy code 

【c】 Dimensional transformation ：reshape

reshape It can help users rearrange the original array according to the new dimension . There are two modes in use , Respectively C Patterns and F Pattern , Fill and read in row by row and column by column respectively .

target = np.arange(8).reshape(2,4)
target
Copy code 
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
Copy code 
target.reshape((4,2), order='C') #  Read and fill by line
Copy code 
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
Copy code 
target.reshape((4,2), order='F') #  Read and fill by column
Copy code 
array([[0, 2],
[4, 6],
[1, 3],
[5, 7]])
Copy code 

Specially , Since the size of the called array is determined ,reshape One dimension is allowed to be vacant , Just fill in -1 that will do ：

target.reshape((4,-1))
Copy code 
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
Copy code 

Next n*1 The size of the array is converted to 1 The operation of dimension group is often used ：

target = np.ones((3,1))
target
Copy code 
array([[1.],
[1.],
[1.]])
Copy code 
target.reshape(-1)
Copy code 
array([1., 1., 1.])
Copy code 

### 3. np Slicing and indexing of arrays

The slice mode of array supports the use of slice Type of start:end:step section , You can also directly pass in the list to specify the index of a dimension for slicing ：

target = np.arange(9).reshape(3,3)
target
Copy code 
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
Copy code 
target[:-1, [0,2]]
Copy code 
array([[0, 2],
[3, 5]])
Copy code 

Besides , It can also be used np.ix_ Use Boolean indexes on the corresponding dimensions , But you can't use slice section ：

target[np.ix_([True, False, True], [True, False, True])]
Copy code 
array([[0, 2],
[6, 8]])
Copy code 
target[np.ix_([1,2], [True, False, True])]
Copy code 
array([[3, 5],
[6, 8]])
Copy code 

When the array dimension is 1 Dimension time , Boolean indexing can be done directly , No need np.ix_

new = target.reshape(-1)
new[new%2==0]
Copy code 
array([0, 2, 4, 6, 8])
Copy code 

### 4. Common functions

For the sake of simplicity , It is assumed that the input arrays of the following functions are one-dimensional .

【a】where

where Is a conditional function , You can specify the fill value corresponding to the position where the condition is met and the position where the condition is not met ：

a = np.array([-1,1,-1,0])
np.where(a>0, a, 5) #  The corresponding position is True Fill when a The corresponding element , Otherwise fill 5
Copy code 
array([5, 1, 5, 5])
Copy code 

【b】nonzero, argmax, argmin

All three functions return indexes ,nonzero Returns the index of a nonzero number ,argmax, argmin Returns the index of the largest and the smallest number respectively ：

a = np.array([-2,-5,0,1,3,-1])
np.nonzero(a)
Copy code 
(array([0, 1, 3, 4, 5], dtype=int64),)
Copy code 
a.argmax()
Copy code 
4
Copy code 
a.argmin()
Copy code 
1
Copy code 

【c】any, all

any When the sequence is at least There is one. True Or non-zero elements True, Otherwise return to False

all Refers to when the sequence element All for True Or non-zero elements True, Otherwise return to False

a = np.array([0,1])
a.any()
Copy code 
True
Copy code 
 a.all()
Copy code 
False
Copy code 

【d】cumprod, cumsum, diff

cumprod, cumsum Represents the cumulative multiplication and accumulation functions, respectively , Returns an array of the same length ,diff Represents the difference from the previous element , Because the first element is a missing value , So by default , The return length is the original array minus 1

a = np.array([1,2,3])
a.cumprod()
Copy code 
array([1, 2, 6], dtype=int32)
Copy code 
a.cumsum()
Copy code 
array([1, 3, 6], dtype=int32)
Copy code 
np.diff(a)
Copy code 
array([1, 1])
Copy code 

【e】 Statistical function

Common statistical functions include max, min, mean, median, std, var, sum, quantile, Quantile calculation is a global method , So it can't pass array.quantile Method call for ：

target = np.arange(5)
target
Copy code 
array([0, 1, 2, 3, 4])
Copy code 
target.max()
Copy code 
4
Copy code 
np.quantile(target, 0.5) # 0.5 quantile
Copy code 
2.0
Copy code 

But for arrays with missing values , They also return missing values , If you need to skip missing values , You have to use nan* Function of type , The above statistical functions have corresponding nan* function .

target = np.array([1, 2, np.nan])
target
Copy code 
array([ 1.,  2., nan])
Copy code 
target.max()
Copy code 
nan
Copy code 
np.nanmax(target)
Copy code 
2.0
Copy code 
np.nanquantile(target, 0.5)
Copy code 
1.5
Copy code 

For covariance and correlation coefficient, we can use cov, corrcoef The calculation is as follows ：

target1 = np.array([1,3,5,9])
target2 = np.array([1,5,3,-9])
np.cov(target1, target2)
Copy code 
array([[ 11.66666667, -16.66666667],
[-16.66666667,  38.66666667]])
Copy code 
np.corrcoef(target1, target2)
Copy code 
array([[ 1.        , -0.78470603],
[-0.78470603,  1.        ]])
Copy code 

Last , It needs to be explained Numpy Of statistical functions in an array axis Parameters , It can calculate the statistical characteristics of a certain dimension , When axis=0 When the result is a column of statistical indicators , When axis=1 When the result is a row of statistical indicators ：

target = np.arange(1,10).reshape(3,-1)
target
Copy code 
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Copy code 
target.sum(0)
Copy code 
array([12, 15, 18])
Copy code 
target.sum(1)
Copy code 
array([ 6, 15, 24])
Copy code 

### 5. Broadcast mechanism

The broadcast mechanism is used to handle the operation between two arrays of different dimensions , Here we only discuss the array broadcast mechanism which is no more than two dimensions .

【a】 Scalar and array operations

When a scalar and an array operate , The scalar will automatically expand the size to the size of the array , Then perform element by element operation ：

res = 3 * np.ones((2,2)) + 1
res
Copy code 
array([[4., 4.],
[4., 4.]])
Copy code 
res = 1 / res
res
Copy code 
array([[0.25, 0.25],
[0.25, 0.25]])
Copy code 

【b】 Operations between two-dimensional arrays

When two array dimensions are exactly the same , Use the operation of the corresponding element , Otherwise, an error will be reported , Unless the dimension of one of the arrays is $m×1$ perhaps $1×n$, Then it will expand its $1$ The dimension of is the size of the dimension corresponding to another array . for example , $1×2$ Array and $3×2$ When an array is operated on element by element, the first array will be expanded to $3×2$, Assign value to corresponding value during expansion . however , It should be noted that , If the dimension of the first array is $1×3$, Then, because the size on the second dimension does not match and is not $1$, An error at this time .

res = np.ones((3,2))
res
Copy code 
array([[1., 1.],
[1., 1.],
[1., 1.]])
Copy code 
res * np.array([[2,3]]) #  The second array expands the first dimension to 3
Copy code 
array([[2., 3.],
[2., 3.],
[2., 3.]])
Copy code 
res * np.array([[2],[3],[4]]) #  The second array expands the second dimension to 2
Copy code 
array([[2., 2.],
[3., 3.],
[4., 4.]])
Copy code 
res * np.array([[2]]) #  Equivalent to two extensions , The two dimensions of the second array are expanded into 3 and 2
Copy code 
array([[2., 2.],
[2., 2.],
[2., 2.]])
Copy code 

【c】 Operation of one-dimensional array and two-dimensional array

When a one-dimensional array $A_k$ And two-dimensional array $B_{m,n}$ In operation , It is equivalent to treating a one-dimensional array as $A_{1,k}$ Two dimensional array of , The broadcast rules used are the same as 【b】 In the agreement , When $k!=n$ And $k,n$ Are not $1$ Times wrong .

np.ones(3) + np.ones((2,3))
Copy code 
array([[2., 2., 2.],
[2., 2., 2.]])
Copy code 
np.ones(3) + np.ones((2,1))
Copy code 
array([[2., 2., 2.],
[2., 2., 2.]])
Copy code 
np.ones(1) + np.ones((2,3))
Copy code 
array([[2., 2., 2.],
[2., 2., 2.]])
Copy code 

### 6. Calculation of vectors and matrices

【a】 Vector inner product ：dot

$\rm \mathbf{a}\cdot\mathbf{b} = \sum_ia_ib_i$

a = np.array([1,2,3])
b = np.array([1,3,5])
a.dot(b)
Copy code 
22
Copy code 

【b】 Vector norm and matrix norm ：np.linalg.norm

In the calculation of matrix norm , most important of all ord Parameters , The optional values are as follows ：

ord norm for matrices norm for vectors
None Frobenius norm 2-norm
'fro' Frobenius norm /
'nuc' nuclear norm /
inf max(sum(abs(x), axis=1)) max(abs(x))
-inf min(sum(abs(x), axis=1)) min(abs(x))
0 / sum(x != 0)
1 max(sum(abs(x), axis=0)) as below
-1 min(sum(abs(x), axis=0)) as below
2 2-norm (largest sing. value) as below
-2 smallest singular value as below
other / sum(abs(x)**ord)**(1./ord)
matrix_target =  np.arange(4).reshape(-1,2)
matrix_target
Copy code 
array([[0, 1],
[2, 3]])
Copy code 
np.linalg.norm(matrix_target, 'fro')
Copy code 
3.7416573867739413
Copy code 
np.linalg.norm(matrix_target, np.inf)
Copy code 
5.0
Copy code 
np.linalg.norm(matrix_target, 2)
Copy code 
3.702459173643833
Copy code 
vector_target =  np.arange(4)
vector_target
Copy code 
array([0, 1, 2, 3])
Copy code 
np.linalg.norm(vector_target, np.inf)
Copy code 
3.0
Copy code 
np.linalg.norm(vector_target, 2)
Copy code 
3.7416573867739413
Copy code 
np.linalg.norm(vector_target, 3)
Copy code 
3.3019272488946263
Copy code 

【c】 Matrix multiplication ：@

$\rm [\mathbf{A}_{m\times p}\mathbf{B}_{p\times n}]_{ij} = \sum_{k=1}^p\mathbf{A}_{ik}\mathbf{B}_{kj}$

a = np.arange(4).reshape(-1,2)
a
Copy code 
array([[0, 1],
[2, 3]])
Copy code 
b = np.arange(-4,0).reshape(-1,2)
b
Copy code 
array([[-4, -3],
[-2, -1]])
Copy code 
[email protected]
Copy code 
array([[ -2,  -1],
[-14,  -9]])
Copy code 

## 3、 ... and 、 practice

### Ex1： Write matrix multiplication using list derivation

The general matrix multiplication is based on the formula , It can be written by a triple loop , Please rewrite it in the form of list derivation .

M1 = np.random.rand(2,3)
M2 = np.random.rand(3,4)
res = np.empty((M1.shape[0],M2.shape[1]))
for i in range(M1.shape[0]):
for j in range(M2.shape[1]):
item = 0
for k in range(M1.shape[1]):
item += M1[i][k] * M2[k][j]
res[i][j] = item
(np.abs(([email protected] - res) < 1e-15)).all() #  Eliminate numerical errors
Copy code 
True
Copy code 

### Ex2： Update the matrix

Let's set the matrix $A_{m×n}$ , Right now $A$ Each element in the is updated to generate a matrix $B$ , The update method is $B_{ij}=A_{ij}\sum_{k=1}^n\frac{1}{A_{ik}}$ , For example, the following matrix is $A$ , be $B_{2,2}=5\times(\frac{1}{4}+\frac{1}{5}+\frac{1}{6})=\frac{37}{12}$ , Please use Numpy Efficient implementation . \begin{split}A=\left[ \begin{matrix} 1 & 2 &3\\4&5&6\\7&8&9 \end{matrix} \right]\end{split}

### Ex3： Chi square statistics

Let's set the matrix $A_{m\times n}$, remember $B_{ij} = \frac{(\sum_{i=1}^mA_{ij})\times (\sum_{j=1}^nA_{ij})}{\sum_{i=1}^m\sum_{j=1}^nA_{ij}}$, Define chi square values as follows ： $\chi^2 = \sum_{i=1}^m\sum_{j=1}^n\frac{(A_{ij}-B_{ij})^2}{B_{ij}}$ Please use Numpy For a given matrix $A$ Calculation $\chi^2$

np.random.seed(0)
A = np.random.randint(10, 20, (8, 5))
Copy code 

### Ex4： Improve the performance of matrix calculation

set up $Z$ by $m×n$ Matrix , $B$ and $U$ Namely $m×p$ and $p×n$ Matrix , $B_i$ by $B$ Of the $i$ That's ok , $U_j$ by $U$ Of the $j$ Column , The following definition $\displaystyle R=\sum_{i=1}^m\sum_{j=1}^n\|B_i-U_j\|_2^2Z_{ij}$, among $\|\mathbf{a}\|_2^2$ It's a vector $a$ Sum of squares of components $\sum_i a_i^2$.

Someone now calculates... Based on the sample data given below $R$ Value , Please make full use of Numpy The function in , Based on this problem, improve the performance of this code .

np.random.seed(0)
m, n, p = 100, 80, 50
B = np.random.randint(0, 2, (m, p))
U = np.random.randint(0, 2, (p, n))
Z = np.random.randint(0, 2, (m, n))
def solution(B=B, U=U, Z=Z):
L_res = []
for i in range(m):
for j in range(n):
norm_value = ((B[i]-U[:,j])**2).sum()
L_res.append(norm_value*Z[i][j])
return sum(L_res)
solution(B, U, Z)
Copy code 
100566
Copy code 

### Ex5： The maximum length of a continuous integer

Enter an integer of Numpy Array , Returns the maximum length of a subarray of strictly incremented consecutive integers , Positive refers to the increasing direction . for example , Input [1,2,5,6,7],[5,6,7] Is a subarray of consecutive integers with maximum length , So output 3; Input [3,2,1,2,3,4,6],[1,2,3,4] Is a subarray of consecutive integers with maximum length , So output 4. Please make full use of Numpy The built-in function of .（ Tips ： Consider using nonzero, diff function ）

copyright notice
author[Livingbody],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/01/202201301317184803.html