废话不多说,直接上代码
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。创建的数组值全部为1
arr
=
np.ones(
5
)
print
(arr)
# [1. 1. 1. 1. 1.]
# 如果想要其他值,只需要乘上相应的数即可
arr1
=
np.ones(
5
)
*
8
print
(arr1)
# [8. 8. 8. 8. 8.], 这样就得到了元素全为8的数组
# 如果我想获取二维数组怎么办?
arr2
=
np.ones((
3
,
3
))
# 还是写上相应的维度,不过这里必须要传入元组。为什么?可以看一下源码,def ones(shape, dtype=None, order='C'):,因此两个维度只能作为一个元组整体传给shape
print
(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
=
arr4
print
(arr5)
# [0. 0. 0. 0. 0.]
# 此时修改了arr4,将arr4中索引为0的元素的值换成10
arr4[
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.]
# 此时再修改arr6
arr6[
0
]
=
10
# 打印arr7,会发现对arr6的修改没有影响arr7
print
(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.6767998397336757
print
(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到1
arr6
=
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)
# 3
print
(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很容易计算出是5
arr3
=
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除不开
# 会抛出一个ValueError
try
:
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,不满足标记为False
print
(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))
# 10
print
(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.000191219475806
print
(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
+
2
arr2
=
arr
-
2
arr3
=
arr
*
2
arr4
=
arr
/
2
print
(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去处理,比如作为机器学习的样本等等····
|