2、Python学习之Numpy基础练习

Python学习之Numpy基础练习

之前一直比较习惯于使用R处理数据,进行ML模型训练,最近因工作需要需要使用python进行替代,就专门简单学习一下numpy等相关基本三方库的内容,本片是学习numpy的简单练习和记录,参考了网上比较多的资料与帮助文档,部分练习问题参考了《NumPy进阶修炼80题》的内容,并在此基础上进行了自己的练习扩展,在此说明。

1、查看numpy版本,返回结果为一个字符串

# 全局
sign_split = "=========="*10 +"\n"
# 1、查看numpy版本,返回结果为一个字符串
import numpy as np
print("Q1、The version of numpy is "+np.__version__)
print("这是一个字符串:",type(np.__version__))
print(sign_split)
Q1、The version of numpy is 1.18.5
这是一个字符串: <class 'str'>
====================================================================================================

2、生成一个0元素一维数组

# 2、生成一个0元素一维数组
## 使用函数zeros()有三个参数:
## shape为int或tuple,指定形状;
## dtype指定元素类型,"int"指定为整数
## order指定元素排列的方式,“C”是以行为主,"F"以列为主
array1_size = 10
array1 = np.zeros(array1_size)
print(f"Q2、全0元素的一维数组:{array1},其类型为{type(array1)};")
array2_size = (2,2)
array2 = np.zeros(array2_size,dtype = "int")
print(f"    指定类型为int:\n{array2}")
print(sign_split)
Q2、全0元素的一维数组:[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.],其类型为<class 'numpy.ndarray'>;
    指定类型为int:
[[0 0]
 [0 0]]
====================================================================================================

3、生成一个区间内固定步长的数(一维数组)

# 3、生成一个区间内固定步长的数(一维数组)
## 函数arange([start,] stop[, step,], dtype=None)
range_data = np.arange(0,100,5)
print("Q3、{} 's type is {}".format(range_data,type(range_data)))
print(sign_split)
Q3、[ 0  5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95] 's type is <class 'numpy.ndarray'>
====================================================================================================

4、将一个list转换为数组形式

# 4、将一个list转换为数组形式
alist = list(range(1,15))
result = np.array(alist)
print("Q4、列表{}转换为数组形式为:{}".format(alist,result))
print(sign_split)
## 函数为 array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0),不会指定维度,除非object本身具有维度排列
## 参数object要求为array_like对象(包含内置序列)
## 参数copy是否复制
## 参数order指定排序方式,C以行为主,F列为主
## 参数ndim指定最小维度
Q4、列表[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]转换为数组形式为:[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14]
====================================================================================================

5、创建一个3x3的全部元素为1的矩阵

# 5、创建一个3x3的全部元素为1的矩阵
one_array = np.ones((3,3),dtype="int")
print(f"Q5、元素为1的3x3矩阵为:{one_array}")
## 或者使用array()函数进行创建
one_array1 = np.array([[1,1,1],
                      [1,1,1],
                      [1,1,1]])
print("第二种方法:{one_array1}。")
print(sign_split)
Q5、元素为1的3x3矩阵为:[[1 1 1]
 [1 1 1]
 [1 1 1]]
第二种方法:{one_array1}。
====================================================================================================

6、创建一个2x2的元素为布尔型,取值为一个单一值的矩阵

# 6、创建一个2x2的元素为布尔型,取值为一个单一值的矩阵
bool_array = np.full((2,2),fill_value=True,dtype=bool)
print("Q6、布尔型元素矩阵:{bool_array}")
## np.full(shape, fill_value, dtype=None, order='C')函数返回一个以fill_value为填充值得矩阵
## 或者使用array函数,指定"bool"型,非0元素转为 True;同理,ones()与zeros()也可以
bool_array1=np.array([[1,0],
                      [-1,3]],dtype = "bool")
print(sign_split)
Q6、布尔型元素矩阵:{bool_array}
====================================================================================================

7、创建一个等差数列

# 7、创建一个等差数列
q7_a = np.linspace(start=10,stop=60,num=10,endpoint=False)
q7_b = np.linspace(10,60,10)
q7_c = np.linspace(10,60,10,dtype = "int")
print(f"Q7、including the endpoint:{q7_b};\n do not include: {q7_a}.")
#只保留整数部分
print(f"the type is int32 which will  force the element into int:\n{q7_c}")
print(sign_split)
Q7、including the endpoint:[10.         15.55555556 21.11111111 26.66666667 32.22222222 37.77777778
 43.33333333 48.88888889 54.44444444 60.        ];
 do not include: [10. 15. 20. 25. 30. 35. 40. 45. 50. 55.].
the type is int32 which will  force the element into int:
[10 15 21 26 32 37 43 48 54 60]
====================================================================================================

8、一个3x3矩阵,元素为0~100之间随机数

# 8、一个3x3矩阵,元素为0~100之间随机数
## 该函数不包括最大数
np.random.seed(8)
random_norm = np.random.randint(0,100,(3,3))
## np.random当中有许多随机函数,包含的函数列表如下:
fun_of_nprandom = dir(np.random)
print(f"Q8、随机函数元素矩阵:\n{random_norm}")
print(fun_of_nprandom)
print(sign_split)
Q8、随机函数元素矩阵:
[[67 84  5]
 [90  8 83]
 [63 48 85]]
['BitGenerator', 'Generator', 'MT19937', 'PCG64', 'Philox', 'RandomState', 'SFC64', 'SeedSequence', '__RandomState_ctor', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bit_generator', '_bounded_integers', '_common', '_generator', '_mt19937', '_pcg64', '_philox', '_pickle', '_sfc64', 'absolute_import', 'beta', 'binomial', 'bytes', 'chisquare', 'choice', 'default_rng', 'dirichlet', 'division', 'exponential', 'f', 'gamma', 'geometric', 'get_state', 'gumbel', 'hypergeometric', 'laplace', 'logistic', 'lognormal', 'logseries', 'mtrand', 'multinomial', 'multivariate_normal', 'negative_binomial', 'noncentral_chisquare', 'noncentral_f', 'normal', 'pareto', 'permutation', 'poisson', 'power', 'print_function', 'rand', 'randint', 'randn', 'random', 'random_integers', 'random_sample', 'ranf', 'rayleigh', 'sample', 'seed', 'set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'test', 'triangular', 'uniform', 'vonmises', 'wald', 'weibull', 'zipf']
====================================================================================================

9、扩展:生成元素服从标准高斯分布的矩阵

# 9、扩展,生成元素服从标准高斯分布的矩阵
norm_array = np.random.randn(3,3)
## 该函数直接指定每个维度的数据
print(f"Q9、服从标准正态分布的随机矩阵:{norm_array}")
## 当没有参数时,生成一个随机数
norm_array_one = np.random.randn()
print("单个随机数%f"%norm_array_one)
## 生成9个服从标准正态分布的数据,也就是一个一维数组
norm_array_ten = np.random.randn(10)
print("一系列随机数:{}".format(norm_array_ten))
print(sign_split)
Q9、服从标准正态分布的随机矩阵:[[ 1.87669986  0.82447946 -0.73390617]
 [-0.45253635  0.32842213 -0.7673767 ]
 [-0.03490256 -0.73477207 -0.91556616]]
单个随机数0.376281
一系列随机数:[-0.16486411  0.24441738 -1.60360984  0.46974942 -0.45004217 -1.1419394
 -1.65282036 -0.16749629  0.22923684  0.22757048]
====================================================================================================

10、将数据进行重新塑形,如上将9个元素改为3x3矩阵

# 10、将数据进行重新塑形,如上将9个元素改为3x3矩阵
### reshape()函数,order参数指定了元素的排列方式,C默认为先行后列,F则相反
norm_array_reshape = np.random.randn(9)
### 原始数据形状
print(f"Q10、原始数据:\n{norm_array_reshape}")
norm_array_reshape = norm_array_reshape.reshape(3,3,order = "C")
### 进行数据重塑之后
print(f"更改形状为:\n{norm_array_reshape}")
print(sign_split)
Q10、原始数据:
[ 1.92339355  0.87609265 -0.70780119 -0.03014998  1.68037924  0.26595927
 -0.35990366 -0.76335722 -1.11174667]
更改形状为:
[[ 1.92339355  0.87609265 -0.70780119]
 [-0.03014998  1.68037924  0.26595927]
 [-0.35990366 -0.76335722 -1.11174667]]
====================================================================================================

11、进行矩阵转置

# 11、进行矩阵转置
norm_array_reshape_t = norm_array_reshape.T
print(f"Q11、Q10中原始矩阵的转置矩阵为:\n{norm_array_reshape_t}")
print(sign_split)
Q11、Q10中原始矩阵的转置矩阵为:
[[-4.43971151e-01  8.16944918e-01  2.21050165e+00]
 [ 1.70511180e+00  1.72511719e+00 -8.20666264e-01]
 [ 2.13359966e+00 -1.91781213e-03 -6.94750536e-01]]
====================================================================================================

12、查看数据类型、内存大小

# 12、查看数据类型、内存大小
print("Q12、上述问题中矩阵的数据类型为{}".format(norm_array_reshape_t.dtype))
print("其所占用的内存为:{} bytes".format(norm_array_reshape_t.nbytes))
print(f"占用内存的计算等价于元素个数{norm_array_reshape_t.size}*每个元素的占用{norm_array_reshape_t.itemsize}byte:",norm_array_reshape_t.size * norm_array_reshape_t.itemsize)
print(sign_split)
## 延伸,np.ndarray类型具有属性:dtype/ndim/size/itemsize/nbytes/shape等
Q12、上述问题中矩阵的数据类型为float64
其所占用的内存为:72 bytes
占用内存的计算等价于元素个数9*每个元素的占用8byte: 72
====================================================================================================

13、数据类型进行修改

# 13、数据类型进行修改
norm_array_reshape_new = norm_array_reshape.astype("int")
#生成一个copy副本,数据类型为float
print(f"Q13、原数组的数类型为{norm_array_reshape.dtype},原数组为:\n{norm_array_reshape};\n数据类型修改为{norm_array_reshape_new.dtype}:\n",norm_array_reshape_new)
print(sign_split)
Q13、原数组的数类型为float64,原数组为:
[[ 1.92339355  0.87609265 -0.70780119]
 [-0.03014998  1.68037924  0.26595927]
 [-0.35990366 -0.76335722 -1.11174667]];
数据类型修改为int32:
 [[ 1  0  0]
 [ 0  1  0]
 [ 0  0 -1]]
====================================================================================================

14、数据元素访问、切片、元素值修改

# 14、数据元素访问、切片、元素值修改
## 提取第三行第三列的元素
element = norm_array_reshape[2,2]
print(f"Q14、The element row3 col3 is {element};")
## 切片操作:提取第三行所有的数据
element = norm_array_reshape[2,:]
print(f"Q14、切片获取第三行所有数据{element};等价于操作 norm_array_reshape[2,...];")
## 切片与索引操作总结——基本切片与高级索引
### (1) 基本切片:即python中的基本切片操作从一维扩展到n维,形式为[start:stop:step],示例如下:
one_dim = np.arange(0,20)
print("一维数组:{}".format(one_dim))
#### 一维数组:提取索引3到15之间,步长为2
one_dim[3:15:2]
#### 一维数组:不指定停止,则到末尾
one_dim[3:]
#### 一维数组:不指定结束,指定迭代步长,以step迭代到stop
one_dim[3::2]
#### 一维数组:负值索引,即从0索引开始从数组末尾从右向左进行,-1表示最后一个,-2表示倒数第二个
one_dim[-1:]
#### 一维数组:以反向返回全部元素
one_dim[::-1]
#### 扩展到二维数组的基本切片操作,每个维度的基本切片之间使用“,”分割,如提取第一行的第三列,第三行的第一列,第4行的3列
#### 当某一维度全部提取时,可以使用“:”或"..."代替;同时,“...”可以代替省略多个维度
two_dim = np.arange(1,26).reshape(5,5)
print("一个5x5的二维数组:\n{};\n获取1行3列,3行1列,4行3列的元素:{}".format(two_dim,two_dim[[1,3,4],[3,1,3]]))
print("获取数组每个角的元素:rows{}".format(two_dim[[0,0],
                                         [0,two_dim.shape[1]-1]]))
print("获取数组每个角的元素:cols{}".format(two_dim[[two_dim.shape[0]-1,two_dim.shape[0]-1],
                                         [0,two_dim.shape[1]-1]]))
### (2)高级索引,与基本切片不同,切片返回的都是原数据的一个视图引用,而高级索引则会始终返回一个数据的副本;
###高级索引分为整数索引与逻辑索引两种——整数索引对不同维度的索引可以使用整数列表,列表元素对应不同的行/列,同时允许对同一行/列重复索引,如下:
print("提取第1/3/5/1行的元素:\n",two_dim[[0,2,4,0]])
print("提取第2,4,1,4列元素:\n",two_dim[:,[1,3,0,3]])
#如果行列维度全部使用整数索引,其会对行列整数列表进行匹配,验证是否符合广播规则,对应位置的整数索引确定一个元素
print("提取(3,2),(3,4),(4,0)(3,0)等4个元素:\n",two_dim[[3,3,4,3],[2,4,0,0]])
print("提取(2,2),(1,2),(4,2)(3,2)等4个元素:\n",two_dim[[2,1,4,3],[2]])
#布尔索引,可以是对应元素,也可以是对应行列,返回的同样是一个副本
print("提取所有偶数:",two_dim[two_dim%2==0])
print("提取第1,3行:\n",two_dim[[True,False,True,False,False]])
print("提取(0,0),(3,4):\n",two_dim[[True,False,False,True,False],[True,False,False,False,True]])
print(sign_split)
Q14、The element row3 col3 is -1.111746666137912;
Q14、切片获取第三行所有数据[-0.35990366 -0.76335722 -1.11174667];等价于操作 norm_array_reshape[2,...];
一维数组:[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
一个5x5的二维数组:
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]
 [21 22 23 24 25]];
获取1行3列,3行1列,4行3列的元素:[ 9 17 24]
获取数组每个角的元素:rows[1 5]
获取数组每个角的元素:cols[21 25]
提取第1/3/5/1行的元素:
 [[ 1  2  3  4  5]
 [11 12 13 14 15]
 [21 22 23 24 25]
 [ 1  2  3  4  5]]
提取第2,4,1,4列元素:
 [[ 2  4  1  4]
 [ 7  9  6  9]
 [12 14 11 14]
 [17 19 16 19]
 [22 24 21 24]]
提取(3,2),(3,4),(4,0)(3,0)等4个元素:
 [18 20 21 16]
提取(2,2),(1,2),(4,2)(3,2)等4个元素:
 [13  8 23 18]
提取所有偶数: [ 2  4  6  8 10 12 14 16 18 20 22 24]
提取第1,3行:
 [[ 1  2  3  4  5]
 [11 12 13 14 15]]
提取(0,0),(3,4):
 [ 1 20]
====================================================================================================

15、对数据元素进行修改、访问

# 15、对数据元素进行修改、访问
####将矩阵的某一元素放大10倍
result_15 = np.arange(20).reshape(4,5)
result_15[2,3] = result_15[2,3] * 100
print("Q15、更改之后",result_15,sep = "\n")
####提取所有的偶数
print("Q15、所有的偶数:",result_15[result_15%2 == 0],sep="\n")

####对所有的奇数进行修改
result_15[result_15%2 == 1] = 667
print("Q15、对奇数进行修改",result_15,sep = "\n")

####交换列,交换行操作
result_15_col = result_15[:,[0,1,3,2,4]]
print("Q15、交换第3列和第4列:",result_15_col,sep = "\n")
result_15_row = result_15[[0,2,1,3],...]
print("Q15、交换第2行与第3行:",result_15_row,sep="\n")
Q15、更改之后
[[   0    1    2    3    4]
 [   5    6    7    8    9]
 [  10   11   12 1300   14]
 [  15   16   17   18   19]]
Q15、所有的偶数:
[   0    2    4    6    8   10   12 1300   14   16   18]
Q15、对奇数进行修改
[[   0  667    2  667    4]
 [ 667    6  667    8  667]
 [  10  667   12 1300   14]
 [ 667   16  667   18  667]]
Q15、交换第3列和第4列:
[[   0  667  667    2    4]
 [ 667    6    8  667  667]
 [  10  667 1300   12   14]
 [ 667   16   18  667  667]]
Q15、交换第2行与第3行:
[[   0  667    2  667    4]
 [  10  667   12 1300   14]
 [ 667    6  667    8  667]
 [ 667   16  667   18  667]]

16、判断两个矩阵的元素是否不相等

# 16、判断两个矩阵的元素是否不相等
result_bool = result_15 == result_15_col
print("Q16、对于两个等规模矩阵比较,其实际上是对应元素的比较,结果为矩阵:\n",result_bool)
## 使用逻辑判断all方法,即所有元素是否为True
print("所有元素是否相等:",result_bool.all())
print("每一列元素是否相等;",result_bool.all(axis = 0))
print("判断每一行的元素是否相等:\n",result_bool.all(axis = 1,keepdims = True))

## 使用any逻辑判断是否有相等的元素
print("所有元素是否有相等的元素",result_bool.any())

## 计算两个矩阵不同元素的个数
print("不同元素的个数——使用总数减去相同元素的个数:",result_bool.size-np.sum(result_bool))
#使用argwhere()函数用于返回非0元素在矩阵/数组当中的索引,一个元素的索引以元组形式包裹,因此要用len()计算非0 True的元素个数
print("不同元素的个数——使用argwhere()函数获取非零元素的位置:",len(np.argwhere(result_15 != result_15_col)))
#或者求和也可以
print("不同元素的个数——对逻辑矩阵求和:",np.sum(result_15 != result_15_col))
#应用,找到大于10的元素
print("使用argwhere找到大于10的元素位置,结果为坐标:\n",np.argwhere(result_15>10))
#首先进行深度copy,避免引用修改
result_15_copy = result_15.copy()
result_15_copy[result_15_copy>10] = 10
print("将大于10的元素修改为10:\n",result_15_copy)
print(sign_split)
Q16、对于两个等规模矩阵比较,其实际上是对应元素的比较,结果为矩阵:
 [[ True  True False False  True]
 [ True  True False False  True]
 [ True  True False False  True]
 [ True  True False False  True]]
所有元素是否相等: False
每一列元素是否相等; [ True  True False False  True]
判断每一行的元素是否相等:
 [[False]
 [False]
 [False]
 [False]]
所有元素是否有相等的元素 True
不同元素的个数——使用总数减去相同元素的个数: 8
不同元素的个数——使用argwhere()函数获取非零元素的位置: 8
不同元素的个数——对逻辑矩阵求和: 8
使用argwhere找到大于10的元素位置,结果为坐标:
 [[0 1]
 [0 3]
 [1 0]
 [1 2]
 [1 4]
 [2 1]
 [2 2]
 [2 3]
 [2 4]
 [3 0]
 [3 1]
 [3 2]
 [3 3]
 [3 4]]
将大于10的元素修改为10:
 [[ 0 10  2 10  4]
 [10  6 10  8 10]
 [10 10 10 10 10]
 [10 10 10 10 10]]
====================================================================================================

17、数值计算(矩阵计算)

# 17、数值计算(矩阵计算)
## 做矩阵乘法,要求两个矩阵符合矩阵乘法格式
a = np.array([[1,3,5,7,9]])
b = np.arange(1,10,2).reshape((5,1))
print(f"Q17、矩阵a形状为:{a.shape}——{a};\n矩阵b的形状为:{b.shape}——{b};\n a*b为结果:{np.dot(a,b)}")

## 数组乘法,即对应元素相乘,若形状不一致则检验是否符合广播规则
print(f"上述两个数组相乘,广播规则均变成5*5的矩阵:\n{a*b}")
print(f"或者调用multiply方法:\n{np.multiply(a,b)}")

## 计算行列式/逆矩阵
np.random.seed(1234)
result_det = np.random.rand(4,4)*10
print("生成一个随机矩阵:\n",result_det)
print("计算矩阵的行列式:",np.linalg.det(result_det))
print("求该矩阵的逆矩阵:\n",np.linalg.inv(result_det))
print("验证逆矩阵,矩阵相乘结果,近似为单位矩阵:\n",np.dot(result_det,np.linalg.inv(result_det)))
print(sign_split)
Q17、矩阵a形状为:(1, 5)——[[1 3 5 7 9]];
矩阵b的形状为:(5, 1)——[[1]
 [3]
 [5]
 [7]
 [9]];
 a*b为结果:[[165]]
上述两个数组相乘,广播规则均变成5*5的矩阵:
[[ 1  3  5  7  9]
 [ 3  9 15 21 27]
 [ 5 15 25 35 45]
 [ 7 21 35 49 63]
 [ 9 27 45 63 81]]
或者调用multiply方法:
[[ 1  3  5  7  9]
 [ 3  9 15 21 27]
 [ 5 15 25 35 45]
 [ 7 21 35 49 63]
 [ 9 27 45 63 81]]
生成一个随机矩阵:
 [[1.9151945  6.22108771 4.37727739 7.85358584]
 [7.79975808 2.72592605 2.76464255 8.01872178]
 [9.58139354 8.75932635 3.5781727  5.00995126]
 [6.83462935 7.12702027 3.70250755 5.61196186]]
计算矩阵的行列式: -94.57300877029733
求该矩阵的逆矩阵:
 [[-0.23848859  0.05361417 -0.20658403  0.44156561]
 [ 0.48973131 -0.04220755  1.05266069 -1.56477811]
 [-1.26037048 -0.31303309 -2.94733888  4.84225976]
 [ 0.50003678  0.19483176  0.85926023 -1.56705186]]
验证逆矩阵,矩阵相乘结果,近似为单位矩阵:
 [[ 1.00000000e+00  2.22044605e-16  0.00000000e+00  0.00000000e+00]
 [-8.88178420e-16  1.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-8.88178420e-16  0.00000000e+00  1.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]
====================================================================================================

18、对两个矩阵进行拼接/重复

# 18、对两个矩阵进行拼接/重复
np.random.seed(12345)
result_1 = np.random.randint(0,100,size = 16).reshape((4,4))
result_2 = np.random.randint(50,150,size = 16).reshape((4,4))
print(f"Q18、矩阵left:\n{result_1}\n矩阵right:\n{result_2}")
print("水平方向进行拼接:\n",np.hstack((result_1,result_2)))
print("垂直方向进行拼接:\n",np.vstack([result_1,result_2]))
#print("水平方向拼接,stack()参数axis = 1为列增水平方向:\n",np.stack([result_1,result_2],axis =0))

## np.pad(array, pad_width, mode='constant', **kwargs)函数
###功能:对矩阵进行填充扩展,对二维数组来讲,主要是在left/top/right/bottom4个方向上进行指定填充
###参数pad_width,指定每个维度上左右要填充的数据个数,以二元元组指定一个维度,元组的个数对应维度个数,多个元组构成一个序列([]或())
###例如二维数组填充,对行填充即列增,为axis = 1方向,对列填充即行增,为axis = 0方向;
###[(1,2),(3,4)]表示top填充一行,bottom填充2行,left填充3列,right填充4列
###参数mode,指定填充的模式:
                        ###"constant",默认模式,即以固定值填充,其后要跟参数constant_values指定填充的数字,可以是单个值,表示四个方向上填充的一样;
                                # 也可以是与pat_width形状一致的,分别制定4个方向上的填充值,每个方向上只能是固定值
                        ###"edge",边缘填充,即使用原来矩阵的外围边缘值进行填充重复,相当于第一行/列,最后一行/列按照pad_width维度进行相应重复
                        ###"linear_ramp",线性等差填充,即由end_values参数指定每个方向上填充后的最外围的值,而与原数组中间要填充的值则是通过原数组的边缘值
                                # 与相应方向的end_value值之间进行等差划分确定的,其等差大致由abs(edge_value - end_value)/(该方向上的填充个数)确定,也有特殊情况
                        ###"maximum",最大值填充,即使用原数组当中的最大值,或者每个轴上(行、列)的最大值进行填充;
                        ###"mean",均值填充,即使用原数组的均值,或者每个轴上(行、列)的最大值进行填充;
                        ###"median",中位值填充,与上述类似;
                        ###"reflect",对称填充,即以原数组的edge边缘值为轴,进行镜像对称;
                                # 当填充的长度超出原数组边缘值得第一次镜像对称时,再次对镜像对称后的数组执行一次镜像对称,然后截取需要的填充长度;
                        ###"symmetric",对称填充,与reflect的区别在于不以边缘值为轴对称,是完全以数组边缘为界镜像反转整个列/行来重复的;
                                # 其后跟随参数reflect_type,指定对称扩展的方式,默认情况下边缘值附近的反转是不变的;
                                # 指定为odd时,扩展获得的元素,为2倍的边缘值减去镜像反转后的元素值得取值
                        ###"wrap",绕封填充,即用原数组后边的填充前边(左边填充右边),前边的填充后边;与reflect的以边缘值进行镜像对称类似,这是以边缘值
                                #为界,进行的平移(顺序不变),而非镜像对称;
                        ###"empty",即空值填充;
###参数stat_length,与reflect_type、end_values等一样为可选参数,主要配合“maximum”/“mean”/"median"/"minimum"四个模式,主要指定各个维度上计算这些
####统计量要用到多少元素,其格式与pad_width相同;
print("原数组:",result_1,sep="\n")
print("线性等差模式:",np.pad(result_1,[(1,2),(3,4)],mode="linear_ramp",end_values = [(0,1),(2,3)]),sep="\n")
print("进行均值填充:",np.pad(result_1,[(1,2),(3,4)],mode="mean"),sep="\n")
print("进行最值填充:",np.pad(result_1,[(1,2),(3,4)],mode="maximum"),sep ="\n")
print("进行镜像对称填充,reflect参数为odd:",np.pad(result_1,[(1,2),(3,4)],mode="reflect",reflect_type = 'odd'),sep="\n")
print(f"进行镜像对称填充,reflect参数为默认:",np.pad(result_1,[(1,2),(3,4)],mode="reflect"),sep="\n")
print(sign_split)
Q18、矩阵left:
[[98 29  1 36]
 [41 34 29  1]
 [59 14 91 80]
 [73 11 77 10]]
矩阵right:
[[131 132  88  57]
 [ 93  73  79 106]
 [105  81 111 147]
 [141 137  86 114]]
水平方向进行拼接:
 [[ 98  29   1  36 131 132  88  57]
 [ 41  34  29   1  93  73  79 106]
 [ 59  14  91  80 105  81 111 147]
 [ 73  11  77  10 141 137  86 114]]
垂直方向进行拼接:
 [[ 98  29   1  36]
 [ 41  34  29   1]
 [ 59  14  91  80]
 [ 73  11  77  10]
 [131 132  88  57]
 [ 93  73  79 106]
 [105  81 111 147]
 [141 137  86 114]]
原数组:
[[98 29  1 36]
 [41 34 29  1]
 [59 14 91 80]
 [73 11 77 10]]
线性等差模式:
[[ 2  1  0  0  0  0  0  0  1  2  3]
 [ 2 34 66 98 29  1 36 27 19 11  3]
 [ 2 15 28 41 34 29  1  1  2  2  3]
 [ 2 21 40 59 14 91 80 60 41 22  3]
 [ 2 25 49 73 11 77 10  8  6  4  3]
 [ 2 13 25 37  6 39  5  4  4  3  3]
 [ 2  1  1  1  1  1  1  1  2  2  3]]
进行均值填充:
[[43 43 43 68 22 50 32 43 43 43 43]
 [41 41 41 98 29  1 36 41 41 41 41]
 [26 26 26 41 34 29  1 26 26 26 26]
 [61 61 61 59 14 91 80 61 61 61 61]
 [43 43 43 73 11 77 10 43 43 43 43]
 [43 43 43 68 22 50 32 43 43 43 43]
 [43 43 43 68 22 50 32 43 43 43 43]]
进行最值填充:
[[98 98 98 98 34 91 80 98 98 98 98]
 [98 98 98 98 29  1 36 98 98 98 98]
 [41 41 41 41 34 29  1 41 41 41 41]
 [91 91 91 59 14 91 80 91 91 91 91]
 [77 77 77 73 11 77 10 77 77 77 77]
 [98 98 98 98 34 91 80 98 98 98 98]
 [98 98 98 98 34 91 80 98 98 98 98]]
进行镜像对称填充,reflect参数为odd:
[[ 239  337  286  155   24  -27   71  169  118  -13 -144]
 [ 160  195  167   98   29    1   36   71   43  -26  -95]
 [  81   53   48   41   34   29    1  -27  -32  -39  -46]
 [  38   27  104   59   14   91   80   69  146  101   56]
 [ 136   69  135   73   11   77   10  -57    9  -53 -115]
 [ 234  111  166   87    8   63  -60 -183 -128 -207 -286]
 [ 191   85  222  105  -12  125   19  -87   50  -67 -184]]
进行镜像对称填充,reflect参数为默认:
[[ 1 29 34 41 34 29  1 29 34 41 34]
 [36  1 29 98 29  1 36  1 29 98 29]
 [ 1 29 34 41 34 29  1 29 34 41 34]
 [80 91 14 59 14 91 80 91 14 59 14]
 [10 77 11 73 11 77 10 77 11 73 11]
 [80 91 14 59 14 91 80 91 14 59 14]
 [ 1 29 34 41 34 29  1 29 34 41 34]]
====================================================================================================

19、统计计算(求和等)

# 19、统计计算(求和等)
##对矩阵进行按列、按行求和等,主要通过axis参数指定轴向
print("Q19、按列求和,即行增方向,指定axis = 0:",np.sum(result_1,axis=0))
print("按行求和,即列增方向,指定axis = 1:",np.sum(result_1,axis=1))
print("未指定axis时,对全部元素求和:",np.sum(result_1))
print("同样求均值等也一样,按行求均值:",np.mean(result_1,axis=1))
##查找最值同样
print("查找行最大值:",np.max(result_1,axis=1))
print("查找列最小值:",np.min(result_1,axis=0))
##获取唯一出现的元素,或者统计各个元素出现了多少次
counters = np.unique(result_1,return_counts=True)
print(f"查找每个元素出现的次数,返回结果为一个元组——\n第一个数组为唯一出现的值:{counters[0]};\n第二个数组为次数统计:{counters[1]}")
##进行排序
print("原始数组:",result_1)
print("使用sort函数,默认对行进行排序(从小到大),axis = 0对每列排序,kind指定了排序算法:\n",np.sort(result_1,axis=0))
print("使用argsort函数,默认对每行排序,从小到大,返回的是索引排序index:\n",np.argsort(result_1,axis= 1))
###延伸——order参数主要用来对带有定义字段的array的排序,每个数据元素都相当于一个复杂的结构体结构,拥有许多属性字段,order则指定了按照
###哪个字段进行排序,示例如下:
####(1)首先创建一个数据类型对象,如student_dt,四个字段
student_dt = np.dtype([("name","S10"),
                      ("age","i1"),
                       ("grade","f4"),
                       ("school","S20")])
#####延伸:numpy的内置数据类型
# bool_:布尔型数据类型(True 或者 False)——符号简写:b
# int_:默认的整数类型(类似于 C 语言中的 long,int32 或 int64)——符号简写:i(有符号整数)
# intc:与 C 的 int 类型一样,一般是 int32 或 int 64
# intp:用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64)
# nt8:字节(-128 to 127)
# int16:整数(-32768 to 32767)
# int32:整数(-2147483648 to 2147483647)
# int64:整数(-9223372036854775808 to 9223372036854775807)
# uint8:无符号整数(0 to 255)——符号简写:u(无符号整数)
# uint16:无符号整数(0 to 65535)
# uint32:无符号整数(0 to 4294967295)
# uint64:无符号整数(0 to 18446744073709551615)
# float_:float64 类型的简写——符号简写:f(浮点型)
# float16:半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位
# float32:单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位
# float64:双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位
# complex_:complex128 类型的简写,即 128 位复数——符号简写:c(复数浮点型)
# complex64:复数,表示双 32 位浮点数(实数部分和虚数部分)
# complex128:复数,表示双 64 位浮点数(实数部分和虚数部分)
###S,s——字符串类型;m——时间间隔;M——日期时间;U——Unicode字符

#创建一个数组,3行1列的数组
studen_arr = np.array([[("zhang1",20,90,"school1")],[("zhao1",19,86,"school0")],[("wang1",23,89,"school")]],dtype = student_dt)
print("创建的原始数组:\n",studen_arr)
print("按照年龄字段进行排序,从小到大:\n",np.sort(studen_arr,axis=0,order="age"))
print("按照grade字段进行排序,从小到大:\n",np.sort(studen_arr,axis=0,order="grade"))
print("******第三种索引访问方式——字段访问,即针对这种自定义的数据类型,如访问第一个学生的姓名:\n",studen_arr[0,0]["name"])
###对arg**的延伸
#多个函数:有argmax、argmin、argwhere、argsort、argpartition都是返回获取索引值
print(sign_split)
按列求和,即行增方向,指定axis = 0: [271  88 198 127]
按行求和,即列增方向,指定axis = 1: [164 105 244 171]
未指定axis时,对全部元素求和: 684
同样求均值等也一样,按行求均值: [41.   26.25 61.   42.75]
查找行最大值: [98 41 91 77]
查找列最小值: [41 11  1  1]
查找每个元素出现的次数,返回结果为一个元组——
第一个数组为唯一出现的值:[ 1 10 11 14 29 34 36 41 59 73 77 80 91 98];
第二个数组为次数统计:[2 1 1 1 2 1 1 1 1 1 1 1 1 1]
原始数组: [[98 29  1 36]
 [41 34 29  1]
 [59 14 91 80]
 [73 11 77 10]]
使用sort函数,默认对行进行排序(从小到大),axis = 0对每列排序,kind指定了排序算法:
 [[41 11  1  1]
 [59 14 29 10]
 [73 29 77 36]
 [98 34 91 80]]
使用argsort函数,默认对每行排序,从小到大,返回的是索引排序index:
 [[2 1 3 0]
 [3 2 1 0]
 [1 0 3 2]
 [3 1 0 2]]
创建的原始数组:
 [[(b'zhang1', 20, 90., b'school1')]
 [(b'zhao1', 19, 86., b'school0')]
 [(b'wang1', 23, 89., b'school')]]
按照年龄字段进行排序,从小到大:
 [[(b'zhao1', 19, 86., b'school0')]
 [(b'zhang1', 20, 90., b'school1')]
 [(b'wang1', 23, 89., b'school')]]
按照grade字段进行排序,从小到大:
 [[(b'zhao1', 19, 86., b'school0')]
 [(b'wang1', 23, 89., b'school')]
 [(b'zhang1', 20, 90., b'school1')]]
******第三种索引访问方式——字段访问,即针对这种自定义的数据类型,如访问第一个学生的姓名:
 b'zhang1'
====================================================================================================

20、对原始数组进行重复

# 20、对原始数组进行重复
repeat_data = np.random.randint(1,20,size = 15).reshape((3,5))
print("Q20、将数据的每一行重复5次,并非整体重复:\n",np.repeat(repeat_data,repeats=5,axis=0))
print("将数据的每一列重复3次,一列重复完,再重复下一列:\n",np.repeat(repeat_data,repeats=3,axis=1))
print(sign_split)
Q20、将数据的每一行重复5次,并非整体重复:
 [[13 15 17  7  1]
 [13 15 17  7  1]
 [13 15 17  7  1]
 [13 15 17  7  1]
 [13 15 17  7  1]
 [12  6 11 13 13]
 [12  6 11 13 13]
 [12  6 11 13 13]
 [12  6 11 13 13]
 [12  6 11 13 13]
 [10 19 19 19 15]
 [10 19 19 19 15]
 [10 19 19 19 15]
 [10 19 19 19 15]
 [10 19 19 19 15]]
将数据的每一列重复3次,一列重复完,再重复下一列:
 [[13 13 13 15 15 15 17 17 17  7  7  7  1  1  1]
 [12 12 12  6  6  6 11 11 11 13 13 13 13 13 13]
 [10 10 10 19 19 19 19 19 19 19 19 19 15 15 15]]

21、随机抽样

# 21、随机抽样
print("Q21、首先看np.random所包含的方法:")
for rand_method in dir(np.random):
    if rand_method[0].isupper() or rand_method[0] == "_":
        continue
    else:
        print("方法:",rand_method)
print()
## (1)显然,其中抽样函数为choice、shuffle
###choice(a, size=None, replace=True, p=None)从一维数组当中进行随机抽样
rand_choice = np.random.choice(np.arange(1,16),size = 5)
print("从1-15个元素中有放回抽取5个",rand_choice)
###(2)random_sample()返回[0,1)之间服从均匀分布的连续数,对于[a,b)则为(b-a)*random_sample+a
rand_samples = np.random.random_sample(size = 10)
print("返回10-20之间服从均匀分布的10个数:\n",10*rand_samples+10)
### (3)shuffle()对数据进行打乱(洗牌),如果是多维数组,其只会对第一维度进行打乱,而其他维度的保持;比如二维数组,只会对每列的数据进行打乱
###列的顺序不会发生变化;其返回值为None,原地对数据修改
data_shuffle =np.arange(1,16)
np.random.shuffle(data_shuffle)
print("将1—15的顺序进行打乱:",data_shuffle)
print("原二维数组为:\n",result_1)
result_1_copy = result_1.copy()
np.random.shuffle(result_1_copy)
print("对二维数组进行按列打乱顺序,列顺序不变:\n",result_1_copy)
print(sign_split)
首先看np.random所包含的方法:
方法: absolute_import
方法: beta
方法: binomial
方法: bytes
方法: chisquare
方法: choice
方法: default_rng
方法: dirichlet
方法: division
方法: exponential
方法: f
方法: gamma
方法: geometric
方法: get_state
方法: gumbel
方法: hypergeometric
方法: laplace
方法: logistic
方法: lognormal
方法: logseries
方法: mtrand
方法: multinomial
方法: multivariate_normal
方法: negative_binomial
方法: noncentral_chisquare
方法: noncentral_f
方法: normal
方法: pareto
方法: permutation
方法: poisson
方法: power
方法: print_function
方法: rand
方法: randint
方法: randn
方法: random
方法: random_integers
方法: random_sample
方法: ranf
方法: rayleigh
方法: sample
方法: seed
方法: set_state
方法: shuffle
方法: standard_cauchy
方法: standard_exponential
方法: standard_gamma
方法: standard_normal
方法: standard_t
方法: test
方法: triangular
方法: uniform
方法: vonmises
方法: wald
方法: weibull
方法: zipf

从1-15个元素中有放回抽取5个 [14  3  5  9 12]
返回10-20之间服从均匀分布的10个数:
 [19.73229982 16.34054377 18.88421725 14.95414759 13.5161653  17.14230369
 15.03929116 12.25637607 12.4497444  17.928007  ]
将1—15的顺序进行打乱: [15  2 10  8  9  5 12  4  6  7 14  3 13  1 11]
原二维数组为:
 [[98 29  1 36]
 [41 34 29  1]
 [59 14 91 80]
 [73 11 77 10]]
对二维数组进行按列打乱顺序,列顺序不变:
 [[73 11 77 10]
 [41 34 29  1]
 [98 29  1 36]
 [59 14 91 80]]
====================================================================================================

22、元素判断与对比

# 22、元素判断与对比
##提取矩阵中第一行中与第二行元素不重复的元素
a = result_1[0,:]
b = result_1[1,:]
###方法一:循环判断
res = []
for e in a:
    if e not in b:
        res.append(e)
print("第一行:",a,"\n第二行:",b)
print("与第二行相比,第一行中的独有的元素:",res)
###方法二:np.isin(element, test_elements, assume_unique=False, invert=False)即逐个判断element中的元素是否存在于test_element,
###返回结果为一个与element等长的布尔数组,指示相应元素是否存在于test_element中
###"~"符号表示取反
("使用np.isin进行判断a中不存在与b的元素:",a[~np.isin(a,b)])
## 判断一个数组中是否存在全部为0的行
array_bool = np.array([[1,2,3,4],[0,2,3,-3],[np.NAN,np.NAN,np.NAN,np.NAN],[0,0,0,0],[-2,9,0,0]])
##获取布尔判别向量,每个元素指示相应行是否不包含0,再对其取反any,即全部为0的行为True,再取any,即可识别出是否含全部0行
print("该矩阵中是否存在全部为0(False)的行:",(~array_bool.any(axis = 1)).any())
## 判断空行是否存在,并删除空行++如果是包含空值的行,应改为any()而非all()
print(f"矩阵:\n{array_bool};\n是否包含空行:",np.isnan(array_bool).all(axis = 1).any())
print(f"移除空行之后:\n",array_bool[~np.isnan(array_bool).all(axis = 1),:])
## 获取数组当中最后一行出现频率最高的值
(val,index) = np.unique(array_bool[array_bool.shape[0]-1,],
                         return_counts=True)
print("该行出现频率最高值为:",val[np.argmax(index)])

## 获取数组当中与100最接近的元素
data_argmin = np.random.randint(95,100,9).reshape((3,3))
####首先明确为什么要用np.flat将数组展开为一维——因为argmax/argmin返回的值为将数组变为1维之后的索引值
print(f"获取数组:\n{data_argmin};\n当中最接近100的元素值为:",data_argmin.flat[np.argmin(abs(data_argmin-100))])
####如何获取该值在原数组的索引?
appr_value = data_argmin.flat[np.argmin(np.abs(data_argmin-100))]
appr_value_index = np.argwhere(data_argmin == appr_value)
print(f"该值在原数组当中的索引位置为:第{appr_value_index.flat[0]+1}行,第{appr_value_index.flat[1]+1}列")
print(sign_split)
第一行: [98 29  1 36] 
第二行: [41 34 29  1]
与第二行相比,第一行中的独有的元素: [98, 36]
该矩阵中是否存在全部为0(False)的行: True
矩阵:
[[ 1.  2.  3.  4.]
 [ 0.  2.  3. -3.]
 [nan nan nan nan]
 [ 0.  0.  0.  0.]
 [-2.  9.  0.  0.]];
是否包含空行: True
移除空行之后:
 [[ 1.  2.  3.  4.]
 [ 0.  2.  3. -3.]
 [ 0.  0.  0.  0.]
 [-2.  9.  0.  0.]]
该行出现频率最高值为: 0.0
获取数组:
[[99 96 96]
 [99 96 97]
 [98 95 95]];
当中最接近100的元素值为: 99
该值在原数组当中的索引位置为:第1行,第1列
====================================================================================================

23、数值处理

# 23、数值处理
## 进行数据的最大最小归一化
np.random.seed(23)
result_23 = np.random.randint(10,100,size = 12).reshape((3,4))
print("原数组为:\n",result_23)
result_23_min_max = (result_23 - np.min(result_23))/(np.max(result_23)-np.min(result_23))
print("进行最大最小归一化之后,元素在[0,1]之间:\n",result_23_min_max)

## 进行标准化(方差),每一列都是一个维度
result_23_mean = np.mean(result_23,axis=0)
result_23_std = np.std(result_23,axis=0)
result_23_normalize = (result_23 - result_23_mean)/result_23_std
print("进行标准化之后:\n",result_23_normalize)
print(sign_split)
原数组为:
 [[93 50 83 64]
 [41 86 49 35]
 [61 16 55 22]]
进行最大最小归一化之后,元素在[0,1]之间:
 [[1.         0.44155844 0.87012987 0.62337662]
 [0.32467532 0.90909091 0.42857143 0.24675325]
 [0.58441558 0.         0.50649351 0.07792208]]
进行标准化之后:
 [[ 1.30740289 -0.0233253   1.39475594  1.34804727]
 [-1.12063105  1.23624092 -0.89984254 -0.3037853 ]
 [-0.18677184 -1.21291562 -0.4949134  -1.04426197]]
====================================================================================================

24、数据存储与读取(IO)

# 24、数据存储与读取(IO)
##在numpy当中,其可以直接在磁盘上进行文本数据和二进制数据的读写,对于ndarray对象引入了npy文件格式进行存储,其可以保存用于对ndarray进行重建
##的必要的数据、图像、dtype以及其他信息;

## (1)load()与save()函数————保存为npy二进制文件
###默认情况下,save()将数据保存为未压缩的二进制文件,扩展名为npy文件;
###而load()函数则可以从.npy和.npz文件中读取恢复数组对象,或者从python的pickle文件中读取pickle对象;
###另外,在两个函数中都有一个allow_pickle参数,一般默认保存时设置为TRUE,即在保存为npy、npz文件之前对数据对象执行序列化封装;
###而在load加载时则设置为FALSE,这是因为pickle对于错误的数据或者恶意构建的数据并不进行安全校验,因此一般设置为False来对不受信任的数据源进行处理,
###而设置为TRUE时,会在读取之前对数据文件执行反序列化(解封装)操作
ndarray_to_save_npy = np.save(file="arr_to_npy",arr=result_23)
###np.save(file, arr, allow_pickle=True, fix_imports=True)中file为要保存为文件名,扩展名npy;若文件路径末尾没有.npy,则自动添加
print("从npy文件从读取保存的数据,结果为:")
ndarr_to_from_npy = np.load(file="/2_Workspace_dailycode/Python_workspace/jupyter_notebook Workspace/arr_to_npy.npy")
print(ndarr_to_from_npy)

## (2)savetxt()与loadtxt()函数————保存为txt、gzip格式的文本文件
###以简单的txt文本文件存储和读取数组数据;
###np.savetxt(fname,X,fmt='%.18e',delimiter=' ',newline='\n',header='',footer='',comments='# ',encoding=None)
####参数fname,要保存的文件名或者文件句柄(如以open形式打开的),一般为txt文件;也可以以.gz格式保存,标识自动保存为gzip压缩格式
####参数X,要保存的ndarray数组对象
####参数fmt,控制数组数据存储的格式,可以是单个字符串或者字符串元素的序列,当是序列的时候分别对应不同列的格式
####参数delimiter,用以分割不同列的分割字符
####参数newlines,不同行之间的分割符,默认为换行/n
####参数header,用来指定表头,对应每列的列名,为一个完整的字符串,不同列名以delimiter分割————对应参数footer,指定表尾
####参数comments,注释表头和表尾的字符
ndarr_to_txt = np.savetxt(fname="to_txt.txt",X = result_23,delimiter=",",header=",".join(["col1","col2","col3","col4"]))
###上述默认是以%.18e格式,标识精度为18表示小数点后18位输出
###fmt的格式模板:“%[flag]width[.precision]specifier”————参数为:
####flag——指示对齐方式,-表示左对齐,+表示加上+-符号,“0”表示指定宽度超过实际宽度后,左侧用0进行填补;默认为右对齐
####precision——精度,对于不同的数据格式,意义不同,对整数表示最小小数位,对e/f表示小数位后的长度,对s表示最小字符长度
####进一步参考:https://docs.python.org/library/string.html#format-specification-mini-language>`_,Python Documentation
heard_str = ",".join(list(map(lambda x:"".join(["column",str(x)]),
                  list(range(1,result_23.shape[1]+1)))))
np.savetxt(fname="to_txt1.txt",X = result_23,fmt="%4.2u",delimiter=",",header=heard_str,comments="**")
### np.loadtxt(fname,dtype=<class 'float'>,comments='#',delimiter=None,converters=None,skiprows=0,usecols=None,unpack=False,ndmin=0,encoding='bytes',max_rows=None)
####从txt文件中读取数据,要求每一行数据具有相同的数值个数
####参数delimiter,默认为以空白符作为元素的分隔符;
####参数converters,为一个字典,字典的key为列号,value为一个函数,用来将相应的列字符创解析转换为目标值(有函数执行),如处理缺失值;
    ##注意,这里的列号不是最终输出的列,而是原始文件当中的列号
####参数skiprows,整数,表示跳过开头的几行之后再读取数据;
####usecol,整数或整数序列(元组),用以指定读取哪些列,取值表示相应的列索引,从0开始;
ndarr_form_txt = np.loadtxt("to_txt1.txt",dtype=np.int16,delimiter=",",skiprows=1,usecols=(0,2,3),converters={2:lambda x:int(x)*10})
print("只读取1,3,4列数据,对第三列扩大10倍,数据类型设为int16:\n",ndarr_form_txt)

## (3)savez()与savez_compressed()函数————保存为npz格式的二进制文件
###与save()和savetxt()函数不同,这两个函数主要将多个数组对象分别存储为未压缩的npz文件和压缩的npz文件
###当有多个arrays时,可以使用关键字参数为每个数组对象进行关键字命名,也可以直接传入,其会默认为"arr_0","arr_1"等
ndarr_to_npz_uncomp = np.savez("to_npz_uncomp.npz",result_23,result_23_mean)
###从npz当中获取数组,使用load()函数会获得一个类似与字典对象的NpzFile对象,其存储的多个数组对象都将以类似键值对的形式存储,key值要么是默认的
###要么是自己定义的关键字
from_uncomp_npz = np.load("to_npz_uncomp.npz")
print("存储的数组名为:{}".format(from_uncomp_npz.files))
print("通过key值访问arr_0:\n",from_uncomp_npz["arr_0"])
###savez_compressed()除了可以进行压缩,其余使用方法与savez()一致。
print(sign_split)
从npy文件从读取保存的数据,结果为:
[[93 50 83 64]
 [41 86 49 35]
 [61 16 55 22]]
只读取1,3,4列数据,对第三列扩大10倍,数据类型设为int16:
 [[ 93 830  64]
 [ 41 490  35]
 [ 61 550  22]]
存储的数组名为:['arr_0', 'arr_1']
通过key值访问arr_0:
 [[93 50 83 64]
 [41 86 49 35]
 [61 16 55 22]]
====================================================================================================

25、集合操作

# 25、集合操作
##在numpy中关于集合的操作都在np.lib.arraysetops模块中定义,可以通过如下方法查看可以使用的方法:
print("关于numpy中set的操作方法的说明:\n",np.lib.arraysetops.__doc__)
## (1)intersectld():求交集——获得两个数组之间的相同元素
np.random.seed(241)
arr1 = np.random.randint(10,20,size = 6)
arr2 = np.random.randint(10,20,size = 6)
###默认情况下返回的是相同的元素
same_arr_12 = np.intersect1d(arr1,arr2)
###return_indices设置为True时,返回三个值,分别为相同的元素值,相同值在第一个array中的索引indices,在第二个array中的索引,第一次出现的位置
same_value,arr1_index,arr2_index = np.intersect1d(arr1,arr2,return_indices=True)
print("arr1为:",arr1,"\narr2为:",arr2)
print("相同的值(排序后)为:",same_value)
print("相同值(排序后)在arr1当中的索引值与arr2当中的索引值分别为:",arr1_index,arr2_index)
###当设置assume_unique = True时,会假设一个数组当中每个元素都是唯一的,也就是说所有的重复元素都会返回,而不会只返回重复元素第一次出现的位置
print("当参数assume_unique = True时,返回值:\n",np.intersect1d(arr1,arr2,assume_unique=True,return_indices=True))
## (2)setdiffld():求差集——去除一个数组中所包含的另一个数组中的元素,即返回只存在于arr1中的元素
print("arr1与arr2的差集:arr1 - arr2 =",np.setdiff1d(arr1,arr2))
print("arr2与arr1的差集:arr2 - arr1 =",np.setdiff1d(arr2,arr1))
## (3)np.isin(element,element_test),返回一个逻辑向量,与element形状相同,指示相应元素是否存在于element_test当中
## (4)np.in1d(ar1, ar2, assume_unique=False, invert=False),与np.isin()的差别在于该函数只支持1维数组
## (5)union1d():求并集——返回两个一维数组当中(多维会被展开)存在的唯一值,排序后返回
print("返回两个一维数组的并集(排序):",np.union1d(arr1,arr2))
## (6)setxor1d():求异或操作——即返回两个集合中的非共同元素,只属于arr1的元素与只属于arr2的元素的并集
print("返回两个集合的异或——非共同元素的并集,相当于两个差集的并集:",np.setxor1d(arr1,arr2))
## (7)ediff1d(ary, to_end=None, to_begin=None):求差值——返回一个一维数组中相邻元素之间的差值,后一个元素减前一个
###to_end和to_begin表示在输出结果的前后添加的内容
print("一维数组元素之间的差值:",np.ediff1d(arr1))
print("ediff1d()相当于arr[1:]-arr[:-1]:",arr1[1:]-arr1[:-1])
print(sign_split)
关于numpy中set的操作方法的说明:
 
Set operations for arrays based on sorting.

:Contains:
  unique,
  isin,
  ediff1d,
  intersect1d,
  setxor1d,
  in1d,
  union1d,
  setdiff1d

:Notes:

For floating point arrays, inaccurate results may appear due to usual round-off
and floating point comparison issues.

Speed could be gained in some operations by an implementation of
sort(), that can provide directly the permutation vectors, avoiding
thus calls to argsort().

To do: Optionally return indices analogously to unique for all functions.

:Author: Robert Cimrman


arr1为: [17 10 12 18 14 19] 
arr2为: [14 19 17 13 17 14]
相同的值(排序后)为: [14 17 19]
相同值(排序后)在arr1当中的索引值与arr2当中的索引值分别为: [4 0 5] [0 2 1]
当参数assume_unique = True时,返回值:
 (array([14, 14, 17, 17, 19]), array([4, 6, 0, 8, 5], dtype=int64), array([0, 5, 2, 4, 1], dtype=int64))
arr1与arr2的差集:arr1 - arr2 = [10 12 18]
arr2与arr1的差集:arr2 - arr1 = [13]
返回两个一维数组的并集(排序): [10 12 13 14 17 18 19]
返回两个集合的异或——非共同元素的并集,相当于两个差集的并集: [10 12 13 18]
一维数组元素之间的差值: [-7  2  6 -4  5]
ediff1d()相当于arr[1:]-arr[:-1]: [-7  2  6 -4  5]
====================================================================================================

26、修改数组为只读模式——对其修改将报错

# 26、修改数组为只读模式——对其修改将报错
print("查看相关指示变量",result_23.flags)
##设置writeable为False
result_23.flags.writeable = False
print("第1行2列元素为",result_23[0,1])
print("对其修改为1000:")
try:
    result_23[0,1] = 1000
except Exception as e:
    print("修改失败!")
    print("报错信息为:",e)
print(sign_split)
查看相关指示变量   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

第1行2列元素为 50
对其修改为1000:
修改失败!
报错信息为: assignment destination is read-only
====================================================================================================

27、数据的描述性统计分析

28、数值取整——ceil()、floor()、around()

29、取消默认的科学计数显示——对控制台输出进行格式控制

# 27、数据的描述性统计分析——均值、中位数、方差、标准差、相关性矩阵、协方差矩阵、最值
arr1 = np.random.randint(1,100,9).reshape((3,3))
arr2 = np.random.randint(20,80,9).reshape((3,3))
print("矩阵间的相关矩阵,即列与列之间的相关性系数:\n",np.corrcoef(arr1))
print("矩阵的协方差矩阵,1/n∑(x-xbar)(y-ybar):\n",np.cov(arr1))

# 28、数值取整——ceil()、floor()、around()
# 29、取消默认的科学计数显示——对控制台输出进行格式控制
##set_printoptions中有许多参数,用来对输出进行打印格式控制:
##np.set_printoptions(precision=None,threshold=None,edgeitems=None,linewidth=None,suppress=None,nanstr=None,infstr=None,formatter=None,sign=None,floatmode=None,**kwarg)
###参数precision,浮点数的输出精度位数,亦即小数点后的位数,默认为8位
###参数threshold,打印输出所有元素的元素个数门槛值,当数组实际的元素个数小于该值时,数组全部打印输出;反之,元素个数大于该值,则以“...”进行部分省略打印
###参数edgeitems,与上述threshold参数配合使用,当进行省略打印时,该参数决定了每个维度开始和结尾打印出来的元素数,中间的就以“...”代替
###参数linewidth,每一行所能打印的最大字符数,当超过就要换行
###参数suppress,是否要打印显示小数位,即小数点后打印——当为TRUE,则结合精度参数打印浮点小数;为False时,则使用科学计数法输出;
###参数nanstr,当出现非数值元素时,将以该参数指定的字符串替代输出;
###参数infstr,当出现无穷值inf时,以该参数指定的字符串替代输出;
###参数sign,控制正负数的正负符号——取"+"时,遇到正数都会加上“+”;取"-"号时,只有数值小于0才会加上负号;还可以取空格,表示只在正值前边打印一个空白字符;
###参数formatter,一个可调用的字典,用以控制元素格式,key值指示了相应的类型,其后的value为一个lambda函数,表示对相应key类型进行处理,返回值必须是一个string;
    ###单个类型包括:bool,int,timedelta,datetime,float,longfloat,complexfloat,longcomplexfloat,numpystr,object,str
    ###一组类型表示:all,int_kind,float_kind,complex_kind,str_kind
###参数floatmode,控制浮点精度参数precision的解释——
    ###fixed表示始终精确打印小数位数;
    ###unique表示每个数值按需打印适应自己的最小位数,可以不统一,参数precision将被忽略
    ###maxprec表示打印最大位数的小数位,但如果一个数值可以更少位数打印则采用;
    ###maxprec_equal表示打印最大精度的小数位,如果每个数值可以唯一的以更少位数打印,则使用。
    
##关闭科学计数法
np.set_printoptions()
np.set_printoptions(suppress=True)
print("关闭科学计数法表示:\n",np.random.uniform(size = 5)/1000)
##打开科学计数法
np.set_printoptions()
np.set_printoptions(suppress=False)
print("打开科学计数法表示:\n",np.random.uniform(size = 5)/1000)

##控制小数点后的输出
np.set_printoptions()
np.set_printoptions(suppress=True,precision = 4)
print("控制小数点后只有4位:",np.random.uniform(size = 5)/1000)
#恢复默认设置
np.set_printoptions()
print(sign_split)
矩阵间的相关矩阵,即列与列之间的相关性系数:
 [[ 1.     -0.7355  0.9021]
 [-0.7355  1.     -0.3712]
 [ 0.9021 -0.3712  1.    ]]
矩阵的协方差矩阵,1/n∑(x-xbar)(y-ybar):
 [[ 340.3333 -250.6667  582.5   ]
 [-250.6667  341.3333 -240.    ]
 [ 582.5    -240.     1225.    ]]
关闭科学计数法表示:
 [0.0005 0.0009 0.0008 0.001  0.0003]
打开科学计数法表示:
 [0.0002 0.0009 0.0002 0.0009 0.0005]
控制小数点后只有4位: [0.0007 0.001  0.0002 0.001  0.001 ]
====================================================================================================

30、位置查找,即将某个数组当中的元素作为索引,去访问提取另一个数组——apply

# 30、位置查找,即将某个数组当中的元素作为索引,去访问提取另一个数组
arr1 = np.random.randint(1,100,20)
arr_index = np.random.randint(0,20,5)
print(f"从{arr1}当中提取索引为{arr_index}的元素:",np.take(arr1,arr_index))
##take(a, indices, axis=None, out=None, mode='raise')从一个数组中沿某一轴获取元素
##take(arr,indexs,axis = 2)与arr[:,:,indexs]操作等价
##延伸:np.apply_over_axes(),np.apply_along_axis()——将函数应用于数组的某一维度,类似R语言中的apply函数族,这里along为一维操作,
##而over则是在多维上的重复操作,返回的结果是与输入数组一样维度的数组,其形状可以变化
arr2 = np.random.randint(0,100,20).reshape((4,5))
print("原数组:\n",arr2)
print("使用apply_along函数,沿0轴求和:\n",np.apply_along_axis(lambda arr:np.sum(arr),0,arr2))
print(sign_split)
从[33 16 74 66 57 33 14 67 49 18 57 99 14 40 67 35 45 34 53 43]当中提取索引为[16  8 10 15  5]的元素: [45 49 57 35 33]
原数组:
 [[87 28 37 25 28]
 [26 87 59 80 15]
 [88 41 78 50 42]
 [40 26 12 36 43]]
使用apply_along函数,沿0轴求和:
 [241 182 186 191 128]
====================================================================================================
# 31、多条件筛选——其根本在于对数据的逻辑索引
print("筛选大于10小于90的元素:",arr1[(arr1>10)&(arr1<90)])
print(sign_split)
筛选大于10小于90的元素: [33 16 74 66 57 33 14 67 49 18 57 14 40 67 35 45 34 53 43]
====================================================================================================

32、数据标记——数据按需处理

# 32、数据标记——数据按需处理
## 对大于50的标记为1,小于50大于10的标记为0,其余标记为-1
###piecewise(x, condlist, funclist, *args, **kw),给一组条件与相对应的函数,将data的元素依次输入评估其在func上是否满足条件
###每个条件和函数都返回一组满足条件为TRUE的元素,注意条件不能复合
print(arr1)
print("对大于50的标记为1,小于50大于10的标记为0,其余标记为-1:")
print(np.piecewise(arr1,[arr1>50,arr1<=50,arr1<=10],[1,0,-1]))
print("等同于:")
print(np.piecewise(arr1,[arr1>50,arr1<=50,arr1<=10],[lambda x:1,lambda x:0,lambda x:-1]))
[33 16 74 66 57 33 14 67 49 18 57 99 14 40 67 35 45 34 53 43]
对大于50的标记为1,小于50大于10的标记为0,其余标记为-1:
[0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0]
等同于:
[0 0 1 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 0]
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值