numpy基本操作

1 构造方法

1. 使用list构建:

>>> import numpy as np
>>> arr = np.array([1, 2, 3])
>>> print(arr, arr.dtype)
[1 2 3] int32

从例子中,我们可以看到,使用dtype来查看数组中元素的类型。

 

2. 创建一个全0/全1的数组

>>> zero_arr = np.zeros((2, 3))
>>> print(zero_arr)
[[0. 0. 0.]
 [0. 0. 0.]]
>>> one_arr = np.ones((2, 3))
>>> print(one_arr)
[[1. 1. 1.]
 [1. 1. 1.]]

函数的入参是一个tuple,分别代表行和列,上例中创建了两个两行三列的数组。分别是全0和全1。我们也可以使用其他的矩阵来创造全0或者全1的矩阵:ones_like和zeros_like函数能帮助我们

>>> d = np.zeros_like(c)
>>> print(d)
[[0 0]
 [0 0]]
>>> d = np.ones_like(c)
>>> print(d)
[[1 1]
 [1 1]]

 

3. 创建被某个值填充的数组

>>> full_arr = np.full((2, 3), 8)
>>> print(full_arr)
[[8 8 8]
 [8 8 8]]

函数中传入两个参数,一个是一个tuple,tuple的元素表示矩阵有几行几列。第二参数是一个值,表示用什么值填充整个矩阵。

 

4. 创建对角矩阵

>>> diag_mat = np.eye(3)
>>> print(diag_mat)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

上例中穿件了一个3*3的对角矩阵。

 

5. 随机值矩阵

>>> rand_mat = np.random.randn(2,3)
>>> print(rand_mat)
[[-0.179857    0.05689865 -0.50993978]
 [-0.41198704 -2.08951967  0.18763144]]

注意,在这里,入参不是tuple了,变成了两个表示行数和列数的数字。和之前的套路不一样,比较容易搞错。该函数生成的数据符合正太分布。

随机生成0到1之间的数字如下例所示。

>>> rand_mat = np.random.rand(2, 3)
>>> print(rand_mat)
[[0.62627156 0.23020075 0.34346337]
 [0.49663935 0.13988671 0.56145168]]

生成指定范围的整数矩阵如下例,其中第一个参数和第二个参数是范围,为半闭半开区间

>>> rand_mat = np.random.randint(3, 7, (2, 3))
>>> print(rand_mat)
[[4 3 3]
 [6 5 4]]

 

6. 创建一个没有被初始化的矩阵

>>> uninit_mat = np.empty((2, 3))
>>> print(uninit_mat)
[[0.179857   0.05689865 0.50993978]
 [0.41198704 2.08951967 0.18763144]]

 

7. 创建一个指定范围的矩阵

>>> rang_mat = np.arange(15)
>>> print(rang_mat)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

>>> rang_mat2 = np.arange(0, 15, 2)
>>> print(rang_mat2)
[ 0  2  4  6  8 10 12 14]

 

 

2. 矩阵元素的类型

矩阵元素的类型可以使用dtype来访问,参见1.1节。也可以使用函数astype将数组内的元素进行转换:

>>> a = np.arange(3)
>>> print(a, a.dtype)
[0 1 2] int32
>>> b = a.astype(np.float64)
>>> print(b, b.dtype)
[0. 1. 2.] float64

 

3. 矩阵元素的访问

>>> a = np.random.randint(0,10, (2, 3))
>>> print(a)
[[0 5 6]
 [8 4 7]]
>>> a[0, 1]
5
>>> a[1][0]
>>> 8

 

4. 矩阵的size

可以使用shape来查询,也可以使用reshape来改变一个矩阵的size。

>>> print(a)
[[0 5 6]
 [8 4 7]]
>>> print(a)
[[0 5 6]
 [8 4 7]]
>>> a.shape
(2, 3)
>>> b = a.reshape(3,2)
>>> print(b)
[[0 5]
 [6 8]
 [4 7]]

 

5. 切片

行切片和列切片

>>> print(a)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
>>> a[0:2]
array([[0, 1, 2],
       [3, 4, 5]])
>>> a[:, 0:2]
array([[0, 1],
       [3, 4],
       [6, 7]])

同样的,我们也可以在行和列上同时做切片

>>> b = a[1:3, 1:3]
>>> print(b)
[[4 5]
 [7 8]]

这里有一个非常需要注意的问题是,numpy为了加快处理的速度,所以是引用优先的;所有他的切片内的元素,其实是原来矩阵内元素的引用,所以,我改变切片内的值,原来矩阵中的值也会随之而改变

>>> b[0,0] = 10
>>> print(b)
[[10  5]
 [ 7  8]]
>>> print(a)
[[ 0  1  2]
 [ 3 10  5]
 [ 6  7  8]]

在切片和原来的矩阵不需要一起改变的场合,我们必须将切片中的值拷贝出来,形成一个单独的矩阵:

>>> c = a[1:, 1:].copy()
>>> print(a)
[[ 0  1  2]
 [ 3 10  5]
 [ 6  7  8]]
>>> print(c)
[[10  5]
 [ 7  8]]
>>> c[0][0] = 4
>>> print(c)
[[4 5]
 [7 8]]
>>> print(a)
[[ 0  1  2]
 [ 3 10  5]
 [ 6  7  8]]

 

6. 矩阵的逻辑判断和逻辑运算

使用逻辑判断可以得到一个bool值的矩阵,矩阵中的值为原矩阵中所有符合该判断条件的情况:

>>> a = np.random.randn(3, 4)
>>> print(a)
[[-0.20597177 -2.96639491  0.45304223  0.07387349]
 [ 0.95893609  1.31844843 -0.20011805 -0.08828083]
 [-0.53680503 -0.40183503  1.32248556 -0.92480772]]
>>> b = a > 0
>>> print(b)
[[False False  True  True]
 [ True  True False False]
 [False False  True False]]
>>> print(a[a>2])
[]
>>> print(a[a>0])
[0.45304223 0.07387349 0.95893609 1.31844843 1.32248556]

我们可以通过where函数来对矩阵进行逻辑判断,比如,下面的例子完成了矩阵中的阈值化,将所有小于0的值都复制为了0:

>>> zero_mat = np.zeros((3, 4))
>>> b = np.where(a > 0, a, zero_mat)
>>> print(b)
[[0.         0.         0.45304223 0.07387349]
 [0.95893609 1.31844843 0.         0.        ]
 [0.         0.         1.32248556 0.        ]]

第一个参数表示的是一个表示条件的矩阵,我们也可以通过直接输入矩阵去达到这么个效果:

>>> bool_mat = a < 0
>>> print(bool_mat)
[[ True  True False False]
 [False False  True  True]
 [ True  True False  True]]
>>> b = np.where(bool_mat, a, zero_mat)
>>> print(b)
[[-0.20597177 -2.96639491  0.          0.        ]
 [ 0.          0.         -0.20011805 -0.08828083]
 [-0.53680503 -0.40183503  0.         -0.92480772]]

 

7. 矩阵的运算

逐个元素的加/减/乘/除/平方根;直接看例子吧:

加法:

>>> print(b)
[[8 7 6]
 [5 4 3]
 [2 1 0]]
>>> print(a)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
>>> print(a+b)
[[8 8 8]
 [8 8 8]
 [8 8 8]]
>>> print(np.add(a, b))
[[8 8 8]
 [8 8 8]
 [8 8 8]]

减法:

>>> print(a-b)
[[-8 -6 -4]
 [-2  0  2]
 [ 4  6  8]]
>>> print(np.subtract(a, b))
[[-8 -6 -4]
 [-2  0  2]
 [ 4  6  8]]

乘法:

>>> print(a*b)
[[ 0  7 12]
 [15 16 15]
 [12  7  0]]
>>> print(np.multiply(a,b))
[[ 0  7 12]
 [15 16 15]
 [12  7  0]]

除法:

>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(b)
[[9 8 7]
 [6 5 4]
 [3 2 1]]
>>> print(a/b)
[[0.11111111 0.25       0.42857143]
 [0.66666667 1.         1.5       ]
 [2.33333333 4.         9.        ]]
>>> print(np.divide(a, b))
[[0.11111111 0.25       0.42857143]
 [0.66666667 1.         1.5       ]
 [2.33333333 4.         9.        ]]

平方跟:

>>> np.sqrt(a)
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974],
       [2.64575131, 2.82842712, 3.        ]])

求和:

>>> np.sum(a)
45
>>> np.sum(a, axis=0)
array([12, 15, 18])
>>> np.sum(a, axis=1)
array([ 6, 15, 24])
>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

求平均值:

>>> np.mean(a)
5.0
>>> np.mean(a, axis=0)
array([4., 5., 6.])
>>> np.mean(a, axis=1)
array([2., 5., 8.])

求累加值:

>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(np.cumsum(a))
[ 1  3  6 10 15 21 28 36 45]
>>> print(np.cumsum(a, axis =0))
[[ 1  2  3]
 [ 5  7  9]
 [12 15 18]]
>>> print(np.cumsum(a, axis=1))
[[ 1  3  6]
 [ 4  9 15]
 [ 7 15 24]]

求累乘值:

>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(np.cumprod(a))
[     1      2      6     24    120    720   5040  40320 362880]
>>> print(np.cumprod(a, axis=0))
[[  1   2   3]
 [  4  10  18]
 [ 28  80 162]]
>>> print(np.cumprod(a, axis=1))
[[  1   2   6]
 [  4  20 120]
 [  7  56 504]]

矩阵的乘法:

>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(b)
[[9 8 7]
 [6 5 4]
 [3 2 1]]
>>> print(a.dot(b))
[[ 30  24  18]
 [ 84  69  54]
 [138 114  90]]
>>> print(np.dot(a, b))
[[ 30  24  18]
 [ 84  69  54]
 [138 114  90]]

矩阵的转置,其中swapaxes其实是维度的相互转换,在多维的矩阵里面,也可以用来交换其中的某些维度上的数据:

>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(a.T)
[[1 4 7]
 [2 5 8]
 [3 6 9]]
>>> print(np.transpose(a))
[[1 4 7]
 [2 5 8]
 [3 6 9]]
>>> print(np.swapaxes(a, 0, 1))
[[1 4 7]
 [2 5 8]
 [3 6 9]]

矩阵的排序

>>> a = np.random.randn(3, 3)*10
>>> b = a
>>> print(b)
[[-21.13178925   5.86602791  -7.48252941]
 [  2.08921814 -14.81116508  11.49010435]
 [-14.30293195   6.04423917  -8.70793998]]
>>> b.sort(1)
>>> print(b)
[[-21.13178925  -7.48252941   5.86602791]
 [-14.81116508   2.08921814  11.49010435]
 [-14.30293195  -8.70793998   6.04423917]]
>>> b.sort(0)
>>> print(b)
[[-21.13178925  -8.70793998   5.86602791]
 [-14.81116508  -7.48252941   6.04423917]
 [-14.30293195   2.08921814  11.49010435]]

8 broadcasting:

在介绍了矩阵的操作之后,来简单介绍一下numpy的broadcasting操作。在矩阵逐元素加的操作中,我们加上一个全部为某个值的矩阵和加上一个数字是一样的结果,如下:

>>> a = np.arange(9).reshape(3, 3)
>>> b = np.full((3, 3),2)
>>> print(a)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
>>> print(b)
[[2 2 2]
 [2 2 2]
 [2 2 2]]
>>> print(a+b)
[[ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]]
>>> print(a+2)
[[ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]]

为什么加上一个常数会是这样的一个结果呢?这都是numpy中boradcasing机制的结果。我们在执行操作a+2的时候,可以认为2被拉伸到了和a一样的shape,再进行的逐个元素累加。当然,在拉伸的过程中,并不是真正的将每个元素都复制了一次,在内存中使用的是同一个值,因此,a+2的操作比a+b的操作更加高效。

当两个数组在做算术运算的时候(注:矩阵的乘法等操作不符合broadcasting的条件);numpy从后往前逐个比较两个矩阵的shape,当满足(1)相等;(2)其中一个是1;时,满足broadcasting的条件。

我们来看看上面的例子:

A: 3 * 3

B:      1

R: 3 * 3

再看一个其他的例子:

A (2d array):        5 x 4

B (1d array):              4

Result (2d array): 5 x 4

 

 

9 其他操作

降维:

>>> print(b)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
>>> b.ravel()
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> b.ravel('F')    # 按列降维
array([0, 3, 6, 1, 4, 7, 2, 5, 8])

拼接:

>>> a = np.ones((3,3))
>>> b = np.zeros((3,3))
>>> np.concatenate((a, b), axis=0)
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
>>> np.concatenate((a,b), axis=1)
array([[1., 1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0., 0.]])

除此之外,我们还可以使用hstack和vstack函数,从下面的例子中,我们可以看到,vstack是在垂直方向上拼接,因此vstack的作用和np.concatenate((a,b), axis=0)是一样的。而同样的道理,hstack和np.concatenate((a,b), axis=1)是一样的。

>>> np.vstack((a,b))
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.],
       [0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])
>>> np.hstack((a,b))
array([[1., 1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0., 0.]])

切分:

>>> a = np.arange(12).reshape(4,3)
>>> print(a)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>> fst, snd, thd = np.split(a, [1, 3], axis=0)
>>> print(fst)
[[0 1 2]]
>>> print(snd)
[[3 4 5]
 [6 7 8]]
>>> print(thd)
[[ 9 10 11]]

 

10 矩阵的存取

>>> a = np.loadtxt("d:\\np_test.txt", delimiter=',')
>>> print(a)
[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [10. 12.  1.  2.]]

其中文件中的数据为:

>>> a = np.arange(12).reshape(4,3)
>>> print(a)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
>>> np.save("d:\\save_tst", a)
>>> b = np.load("d://save_tst.npy")
>>> print(b)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]

并且,我们可以看到在D盘中多了要给文件save_tst.npy,注意,他会自己加上后缀npy。

 

11 获取最大值或者最小值的索引

我们通过argmin和argmax两个函数来获取最大值或者最小值的索引,如下例所示:

>>> t = [1, 10, 3, 1, 10, 2, 7, 10, 9]
>>> a = np.array(t).reshape(3, 3)
>>> print(a)
[[ 1 10  3]
 [ 1 10  2]
 [ 7 10  9]]
>>> b = np.argmin(a, axis =0)
>>> c = np.argmax(a, axis = 1)
>>> print(b)
[0 0 1]
>>> d = np.argmin(a, axis =1)
>>> print(d)
[0 0 0]

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值