(1) python--numpy
废话不多说,直接上代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import numpy as np# 如何创建一个数组arr = np.array([1, 2, 3, 4])print(arr) # [1 2 3 4]# 查看数组的属性# 数组里元素的总个数print(arr.size) # 4# 数组的形状print(arr.shape) # (4,),表示数组只有一个维度,里面有四个元素# 数组的维度print(arr.ndim) # 1# 数组里元素的类型print(arr.dtype) # int32 |
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
import numpy as np# 快速构建一个固定值的数组# 接受的参数为shape。创建的数组值全部为1arr = np.ones(5)print(arr) # [1. 1. 1. 1. 1.]# 如果想要其他值,只需要乘上相应的数即可arr1 = np.ones(5) * 8print(arr1) # [8. 8. 8. 8. 8.], 这样就得到了元素全为8的数组# 如果我想获取二维数组怎么办?arr2 = np.ones((3, 3)) # 还是写上相应的维度,不过这里必须要传入元组。为什么?可以看一下源码,def ones(shape, dtype=None, order='C'):,因此两个维度只能作为一个元组整体传给shapeprint(arr2)'''[[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]'''# 当然除了ones还有一个zeros(相当于np.empty()),功能是一样的,只是元素的值不一样arr3 = np.zeros(5)print(arr3) # [0. 0. 0. 0. 0.]# 关于拷贝的问题arr4 = np.zeros(5)print(arr4) # [0. 0. 0. 0. 0.]arr5 = arr4print(arr5) # [0. 0. 0. 0. 0.]# 此时修改了arr4,将arr4中索引为0的元素的值换成10arr4[0] = 10# 此时再打印arr5,会发现arr5的值被修改了print(arr5) # [10. 0. 0. 0. 0.]# 原因是arr4,arr5都指向了同一个地址。只要python入门了都能理解,在这里就无须赘述了# 如何解决,使用copy函数arr6 = np.zeros(5)print(arr6) # [0. 0. 0. 0. 0.]arr7 = arr6.copy() # 表示将arr6的值拷贝一份,将arr7指向这个拷贝的值print(arr7) # [0. 0. 0. 0. 0.]# 此时再修改arr6arr6[0] = 10# 打印arr7,会发现对arr6的修改没有影响arr7print(arr7) # [0. 0. 0. 0. 0.]# 获取单位矩阵arr8 = np.eye(5)print(arr8)'''[[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.]]''' |
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
import numpy as np# 创建一定数量的随机数组成的数组# 创建一个元素范围是0到1的数组,里面指定数组的形状,注意这里不需要传入元祖.如果不传参,直接生成一个0到1的一个随机数,和np.random.random()一样arr1 = np.random.rand(2, 2)print(arr1)'''[[0.64132648 0.35386521] [0.5776028 0.19263254]]'''# 这个函数,不需要接受参数,只会生成一个随机数,和python的random.random()一样arr2 = np.random.random()arr3 = np.random.rand() # rand里面不传参的话,两者功能是一样的print(arr2) # 0.6767998397336757print(arr3) # 0.6981771524120665# 创建指定范围内的一个整数,不包括右边结尾arr4 = np.random.randint(1, 3)print(arr4) # 2# 如果指定形状的话,一定要以元组的形式arr5 = np.random.randint(1, 3, (2, 2)) # 表示生成2行2列的数组,数组里面元素为1到3(不包括3)的随机数print(arr5)'''[[1 2] [1 1]]'''# 创建指定范围的一个随机数,不传参的话,默认是0到1arr6 = np.random.uniform(1, 3)print(arr6) # 1.3521449018009046# 这里同样可以传入形状arr7 = np.random.uniform(1, 3, (2, 2))print(arr7)'''[[2.01122666 1.74303599] [2.24118912 1.46172109]]'''# 关于rand,其实还有一个randn,和rand方法类似,只不过返回的是一个-1到1之间的随机数arr8 = np.random.randn(2, 2)print(arr8)'''[[ 0.21272592 -0.7284402 ] [-1.06310727 -0.91317326]]'''# 创建一个正态分布的数组,接受的参数为平均值,标准差(注意不是方差,是标准差),形状arr9 = np.random.normal(1.5, 0.3, (3, 3))print(arr9)'''[[1.67316405 1.36683971 1.80043196] [1.05001658 0.95180213 1.53729273] [2.30675779 1.52553859 1.10877468]]'''# 表示将0到1切割成10份,组成一个数组。如果没有指定切割的数量,默认切割50份arr10 = np.linspace(0, 1, 10)print(arr10)'''[0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556 0.66666667 0.77777778 0.88888889 1. ]''' |
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import numpy as np# 获取数组的部分元素,可以通过索引或者切片# 先生成一个5行5列的数组arr = np.random.randint(1, 10, (5, 5))print(arr)'''[[7 6 5 5 1] [3 4 8 7 8] [8 2 1 1 8] [2 6 1 2 4] [3 8 7 4 9]]'''# 通过索引获取某一个元素# 表示获取第二行,第一个元素。在np.array中是支持这样传值的,当然python的列表是不支持的# 其实在这里也可以通过arr[1][0]获取值的。如果只是获取单个值的话,是没有问题的。但如果通过切片获取一个子数组的话,是不推荐这样做的,原因下面会解释value = arr[1, 0]value1 = arr[1][0]print(value) # 3print(value1) # 3# 通过切片获取一个子数组,表示获取第一行第二行,第二列第三列组成的数组arr1 = arr[1:3, 2: 4]print(arr)'''[[7 6 5 5 1] [3 4 8 7 8] [8 2 1 1 8] [2 6 1 2 4] [3 8 7 4 9]]'''print(arr1)'''[[8 7] [1 1]]'''# 如果通过arr[1: 3][2: 4]的方式获取的话,表示的是先通过arr[1:3]获取arr的第二行到第三行,然后arr[1:3][2:4]表示在arr的第二行到第三行组成的数组的基础上,再获取第三行到第四行,显然索引越界了# 改变数组的形状,通过reshape重塑数组的形状# 由于分割了10分,所以可以组成2行5列,当然我们也可以将5写成-1。如果我们不想计算,只需要指定一个数字,另一个数字写成-1,然后让numpy帮我们计算是多少arr2 = np.linspace(0, 1, 10).reshape(2, 5)print(arr2)'''[[0. 0.11111111 0.22222222 0.33333333 0.44444444] [0.55555556 0.66666667 0.77777778 0.88888889 1. ]]'''# 显然是2的话,那么当我们写入-1,那么numpy很容易计算出是5arr3 = np.linspace(0, 1, 10).reshape(2, -1)print(arr3)'''[[0. 0.11111111 0.22222222 0.33333333 0.44444444] [0.55555556 0.66666667 0.77777778 0.88888889 1. ]]'''# 如果将2改成3的话,会怎么样呢?那么会报错,numpy会发现10除以3除不开# 会抛出一个ValueErrortry: np.linspace(0, 1, 10).reshape(3, -1)except ValueError as e: print(e)'''cannot reshape array of size 10 into shape (3,newaxis)''' |
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
import numpy as np# numpy中的计算# 按条件进行计算arr = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])# 如果我想筛选大于50的元素# arr>50,表示会对数组里的每一个元素执行这个操作,如果满足标记为True,不满足标记为Falseprint(arr > 50) # [False False False False False True True True True True]# 将布尔值映射到数组当中,为True的筛选出来,False的不筛选arr1 = arr[arr > 50]print(arr1) # [ 60 70 80 90 100]# 如果我想筛选大于20并且小于70的元素# 这里为什么使用一个&,在c语言或者go语言中,出现过&&连接两个条件判断语句# 注意&&表示两个条件同时成立才成立,而这里的&表示要将两个由True和False组成的数组进行一个位运算。# 而且,操作符连接的两个数组一定要用括号括起来,否则报错print(arr[(arr > 20) & (arr < 70)]) # [30 40 50 60]# 同理,小于20或者大于70,注意不要写两个||print(arr[(arr < 20) | (arr > 70)]) # [ 10 80 90 100]# 替换,将大于等于50的替换成60,小于50的替换成40# np.where接受三个参数,第一个是条件(再次强调,arr>50,不是将数组和50进行比较,而是将数组中的每一个元素和50进行比较),如果条件满足将该元素的值替换成第二个参数对应的值,否则替换成第三个参数对应的值# np.where具有返回值,返回一个新的数组arr2 = np.where(arr >= 50, 60, 40)print(arr2) # [40 40 40 40 60 60 60 60 60 60]print(arr) # [ 10 20 30 40 50 60 70 80 90 100]# 可以看到arr并没有发生改变# 求数组的最大值或最小值arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])print(arr)'''[[ 1 9] [ 3 8] [ 6 2] [ 5 7] [ 4 10]]'''# 在所有元素之间求最大值,或最小值# 即可以用np.max(arr),也可以使用arr.max(),推荐第一种。一方面是有些功能只能通过np创建,另一方面这样写也比较直观print(np.max(arr)) # 10print(np.min(arr)) # 1# 获取每一行最大值或者最小值print(np.max(arr, axis=1)) # [ 9 8 6 7 10]print(np.min(arr, axis=1)) # [1 3 2 5 4]# 获取每一列的最大值或最小值print(np.max(arr, axis=0)) # [ 6 10]print(np.min(arr, axis=0)) # [1 2]# 获取平均值print(np.mean(arr)) # 5.5# 获取方差print(np.std(arr)) # 2.8722813232690143# 验证# 创建一个平均值为4,标准差为1.5, 形状为50行50列的数组verify_arr = np.random.normal(4, 1.5, (50, 50))print(np.mean(verify_arr)) # 4.000191219475806print(np.std(verify_arr)) # 1.4951340773961896# precentile,接收两个参数# 参数一:array# 参数二:0到100的value,表示value%的分位数在arry对应的值# 这里的50,则表示50%对应的分位数,在array中则正好是中位数,显然25%和75%分别对应左右两个四分位数print(np.percentile(np.array([1, 2, 30, 40, 50]), 50)) # 30.0# 五个元素,元素30对应的分位数是50%,元素2对应的分位数25%,那么20%应该比2小print(np.percentile(np.array([1, 2, 30, 40, 50]), 20)) # 1.8# 所以看到这里就明白了,np.percentile(array, value)返回一个数值,表示array中value%的元素比返回的数值小,(100-value)%的数值比返回的数值大# np.irr,表示内部收益率,函数接收一个列表[n,n1,n2,n3,n4,......],返回一个数值r,其中n = n1/(1+r) + n2/(1+r)^2 + n3/(1+r)^3 + ....# 表示先投了100,然后每个阶段能收回来一部分钱,总共收了五个阶段。收的钱越多,内部收益率越高。print(np.irr([-100, 10, 10, 40, 50, 40])) # 0.1195048121414084# 求矩阵的转置arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])print(arr)'''[[ 1 9] [ 3 8] [ 6 2] [ 5 7] [ 4 10]]'''print(arr.T) # 或者np.transpose(arr),不过arr.T更简洁,而且看起来更酷'''[[ 1 3 6 5 4] [ 9 8 2 7 10]]'''# 求矩阵的逆,关于矩阵的逆矩阵,就是和原矩阵相乘(数学上的运算)得到单位矩阵,因此这就意味传入的要是同型矩阵,即矩阵的行数和列数相等# 当然还有一个函数可以不需要传入同型矩阵arr = np.array([[1, 9], [3, 8]])print(arr)'''[[1 9] [3 8]]'''# np.linalg.inv(arr),返回arr的逆矩阵arr_inv = np.linalg.inv(arr)print(arr_inv)'''[[-0.42105263 0.47368421] [ 0.15789474 -0.05263158]]'''# 相乘之后得到单位矩阵print(np.dot(arr, arr_inv))'''[[1. 0.] [0. 1.]]'''# 非同型矩阵arr = np.array([[1, 9], [3, 8], [6, 2], [5, 7], [4, 10]])arr_inv = np.linalg.pinv(arr)print(arr_inv)'''[[-0.06784661 -0.00572618 0.13430505 0.05639424 -0.00069408] [ 0.05752212 0.02915148 -0.04737116 0.00078084 0.03383654]]'''# 相乘之后会变成一个同型矩阵print(np.dot(arr, arr_inv))'''[[ 0.44985251 0.25663717 -0.2920354 0.06342183 0.30383481] [ 0.25663717 0.21603332 0.02394586 0.17542946 0.2686101 ] [-0.2920354 0.02394586 0.71108798 0.33992712 0.06350859] [ 0.06342183 0.17542946 0.33992712 0.2874371 0.23338539] [ 0.30383481 0.2686101 0.06350859 0.23338539 0.3355891 ]]''' |
|
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import numpy as np# 数组之间的运算arr = np.array([1, 2, 3, 4])arr1 = arr + 2arr2 = arr - 2arr3 = arr * 2arr4 = arr / 2print(arr1) # [3 4 5 6]print(arr2) # [-1 0 1 2]print(arr3) # [2 4 6 8]print(arr4) # [0.5 1. 1.5 2. ]# 再次提示:数组和int进行运算,表示数组当中的每一个值和int进行运算# 如果是二位数组呢?print(np.array([[1, 2], [3, 4]]) + 100)# 依旧对每个元素进行了操作'''[[101 102] [103 104]]'''# 矩阵之间的运算,这里不是简单相乘,而是矩阵之间的运算,所以左矩阵的列数要等于右矩阵的行数。最终运算之后的矩阵的行和列分别和左矩阵的行、右矩阵的列相等# arr1有三列,所以arr2有三行arr1 = np.array([[1, 2, 3], [2, 3, 4]])arr2 = np.array([[1], [2], [3]])print(np.dot(arr1, arr2))'''[[14] [20]]'''# 矩阵的拼接arr1 = np.array([[1, 2, 3], [2, 3, 4]])arr2 = np.array([[3, 4, 5], [4, 5, 6]])print(arr1)'''[[1 2 3] [2 3 4]]'''print(arr2)'''[[3 4 5] [4 5 6]]'''# 上下拼接,注意要传入元组print(np.vstack((arr1, arr2))) # 等价于np.stack((arr1, arr2), axis=0)'''[[1 2 3] [2 3 4] [3 4 5] [4 5 6]]'''print(np.hstack((arr1, arr2))) # 等价于np.stack((arr1, arr2), axis=1)'''[[1 2 3 3 4 5] [2 3 4 4 5 6]]'''# 以上暂时就是关于numpy的一些用法,关于numpy还可以读取文件这里就不介绍了,文件读取可以用另一个基于numpy的更强的库--->pandas# 关于pandas,pandas为python提供了两种数据结构,分别是Series和DataFrame# 我们知道numpy中的array是一个数组,那么Series相当于给array加上了index。而DataFrame相当于是二维的Series# 而且一般做数据清洗的时候,都是使用pandas,然后将清洗过的数据交给numpy。然后由numpy去处理,比如作为机器学习的样本等等···· |


浙公网安备 33010602011771号