0%

numpy入门

1.建立n维数组

1.1 常用方法

1
2
3
4
5
6
7
8
9
10
np.random.random(())
np.random.uniform()
np.ones(())
np.zeros(())
np.arange().reshape()
np.arange().resize()
np.array([])
np.empty()
np.linspace()
np.eys()

1.2 其他方法

np.empty_like()
np.fromfunction()

2.多维数组基本属性

2.2 axis 介绍

2.3 基本属性

ndim
shape
size
data
itemsize
dtype

3.打印、索引、切片、迭代多维数组

3.1 打印与迭代

for row in narr:
print(row)

for i in narr.flag:
print(i)

3.2 切片与索引

以二维数组为例(即矩阵)
取特定数字
narr[i,j]
按行
narr[i] <=> narr[1,:]
按列
narr[,i] <=> narr[:,i]
按区域
narr[i:j,i:j]
特别地:
narr[i,…]语法糖说明:

再以三维数组为例(即矩阵)

3.3 切片和索引的一些小技巧

3.3.1 使用索引数组进行索引

例0:

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
a=np.arange(5)
>>a[[0,1,2]]
array([0, 1, 2])

a=np.arange(12).reshape(3,4)
>>a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])

>>a[([0,1,2],[0,0,0])]
array([0, 4, 8])

>>a[np.array([0,1,2])]
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])

i=np.array([[0,1,2],[0,0,0]])
>>a[i]
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],

[[ 0, 1, 2, 3],
[ 0, 1, 2, 3],
[ 0, 1, 2, 3]]])

j=np.array([0,1,2,0,0,0])
>>a[j]
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 0, 1, 2, 3],
[ 0, 1, 2, 3],
[ 0, 1, 2, 3]])

例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
i为一维数组的索引

a=np.arange(10)**2
i=np.array([1,2,6,5])
>>a[i]
array([ 1, 4, 36, 25], dtype=int32)

i为二维数组的索引
a=np.arange(12).reshape(3,4)**2
i=np.array([1,2])
>>a
array([[ 0, 1, 4, 9],
[ 16, 25, 36, 49],
[ 64, 81, 100, 121]], dtype=int32)
>>a[i]
array([[ 16, 25, 36, 49],
[ 64, 81, 100, 121]], dtype=int32)

例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a=np.arange(16).reshape(4,4)
>>a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
i=np.array([[0,0,1],[2,2,3]])
>>a[i]
array([[[ 0, 1, 2, 3],
[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[ 8, 9, 10, 11],
[12, 13, 14, 15]]])

由例0 不难得例1,2的结果

例3:(多维索引和切片)

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
a=np.arange(12).reshape(3,4)
>>a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
i=np.array([[0,1],[1,2]])
j=np.array([[2,1],[3,3]])
>>a[i]
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],

[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]])

>>a[([0,1,1,2],[2,1,3,3])]
array([ 2, 5, 7, 11])

>>a[i,2] #2逻辑上会被广播为[[2,2],[2,2]]
<=> np.array([np.array([a[0,2],a[1,2]]),np.array([a[1,2],a[2,2]])])
array([[ 2, 6],
[ 6, 10]])

>>a[0,j] #同上,0被广播
array([[2, 1],
[3, 3]])

>>a[0,:] <=>a[0,0],a[0,1],a[0,2],a[0,3]组合
array([0, 1, 2, 3])

>>a[:,1] <=>a[0,1],a[1,1],a[2,1]组合
array([1, 5, 9])

>>a[:,j] <=> a[0,j],a[1,j],a[2,j]三个组合,也有广播
array([[[ 2, 1],
[ 3, 3]],
[[ 6, 5],
[ 7, 7]],
[[10, 9],
[11, 11]]])
>>a[i,:] <=> a[0,:],a[1,:],a[1,:],a[2,:]组合【一定要先确定行,再确定列,认为<=>a[i,0],a[i,1],a[i,2],a[i,3]时,形状是不对的】

array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],

[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]])

>>a[i,j]
array([[ 2, 5],
[ 7, 11]])

l=[i,j]
>>a[l]
array([[ 2, 5],
[ 7, 11]])

3.3.2 使用布尔数组进行索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a = np.arange(12).reshape(3,4)
b=a>4
>>a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>b
array([[False, False, False, False],
[False, True, True, True],
[ True, True, True, True]])

>>a[b]
array([ 5, 6, 7, 8, 9, 10, 11])

a[b]=0
>>a
array([[0, 1, 2, 3],
[4, 0, 0, 0],
[0, 0, 0, 0]])

3.3.3 ix_()函数做索引

1
2
3
4
5
6
7
a=np.arange(10).reshape(2,5)
ixgrid=np.ix_([0,1],[2,4])
>>ixgrid

>>a[ixgrid]
array([[2, 4],
[7, 9]])

4.操作多维数组形状

4.1 改变多维数组形状

reshape()
resize()
reval()
narr.T

4.2 合并多维数组

hstack()
vstack()
column_stack()

4.3 拆分多维数组

hsplit()
vsplit()
array_split()

5.通用函数

np.fromfucntion()
np.where()
np.sort()
np.numpy.apply_along_axis()
np.argmax()
np.argmin()
np.diff()
np.sum()
np.mean()
np.min()
np.max()
np.median()
np.floor()

6.深拷贝与浅拷贝

6.1 完全不复制

1
2
3
4
5
6
a=np.arange(12).reshape(3,4)
b=a
id(a)
id(b)
b.resize(3,4)
#此时a的形状也会发生改变

可以理解为b为a的一个别名

6.2 浅拷贝

1
2
a=np.arange(10)
b=a.view()

b,a指向同一块内存,但b,a不是同一个对象(id(a)!=id(b))

6.3 深拷贝

1
b=a.copy()

直接将a指向的内存单元复制了一份,然后b指向了复制的内存单元

7.广播技术

7.1 广播对象

广播技术是为了让两个形状不同的多维数组‘尽可能的’进行按位置加减而不出错。注意矩阵的乘除没有广播,运算是按照数学定义严格执行的(前矩阵的列数==后矩阵的行数)。

7.2 广播规则:

当操作两个array时,numpy会逐个比较它们的shape(构成的元组tuple),只有在下述情况下,两arrays才算兼容:
他们是相等的,或者其中一个是1

当符合广播规则时,会对运算的多维数组narray进行逻辑上的扩展,以得到结果。(注意,多维数组在物理内存上不会被修改)

扩展规则一:如果所有输入数组不具有相同数量的维度,则将“1”重复地预先添加到较小数组的形状,直到所有数组具有相同数量的维度。
扩展规则二:当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值
举个例子:
如a为二维数组:[[0],[1],[2],[3]] shape=(4,1)
b为一维向量:[1,1,1,1,1] shape=(5,)

1
2
a:(2d array)  4 x 1
b:(1d array) 5

更多解释和介绍,参照:

numpy广播官方文档

numpy广播知乎文章

numpy中文网

由广播规则可得:a+b 可以计算(其中一个是1),下面进行多维数组的逻辑扩展,由扩展规则一可得,b比a少一维,先将b用1填充至与a同一维度,b为[[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]] 此时b.shape=(4,5),由因为a 的axis=1 的轴长度为1,所以再对a进行扩展,此时应用扩展规则二,a扩展后为:[[0,0,0,0,0],[1,1,1,1,1],[2,2,2,2,2],[3,3,3,3,3]] 此时 a.shape=(4,5),最后a+b在按位相加。注意以上都是在逻辑上的扩展,计算时物理内存并未扩展。

8. numpy在线性代数方面的工作

8.1

这一部分参考: https://www.numpy.org.cn/article/basics/numpy_matrices_vectors.html

8.1 向量与矩阵

8.2 解线性方程组

8.3 多元线性回归

9. numpy与机器学习

9.1 numpy与数据分析

9.2 numpy与神经网络

.参考资料

numpy官网

知乎提问

numpy中文网

numpy广播官方文档

numpy广播知乎文章

~未完