Numpy库使用入门

本文主要是学习知乎锦恢的专栏Kirigaya的Python实验室中的numpy教程做记录

(一)ndarray对象的基本操作

引用Numpy库
大家一般都会使用别名“np”来调用numpy:

import numpy as np
1. ndarray对象

ndarray是np处理数据的基本对象,实际上可以理解为一个多维数组(或者看成一个n维张量)。它由两部分构成:

  • 实际的数据
  • 描述这些数据的元数据(数据维度、数据类型等)

NumPy数组类是ndarray,它的别名也被叫做数组,但numpy.array与标准Python库中的数组类array.array是不相同的,标准Python库中的数组类通常只处理一维数组,并且提供了很少的功能。Ndarray对象有以下重要的属性:

ndarray对象的属性

在这里插入图片描述

import numpy as np
a = np.array([1, 2, 3, 4, 5])  # 创建ndarray后面会讲
b = np.array([[1], [2], [3], [4], [5]])
c = np.array([[1, 2], [3, 4]])

print(a.ndim)  # 1
print(b.ndim)  # 2
print(c.ndim)  # 2
print(a.shape)  # (5,)
print(b.shape)  # (5, 1)
print(c.shape)  # (2, 2)
print(a.size)  # 5
print(b.size)  # 5
print(c.size)  # 4 
print(a.dtype)  # int32
print(b.dtype)  # int32
print(c.dtype)  # int32
print(a.itemsize)  # 4     以字节的形式返回数组中每一个元素的大小。
print(b.itemsize)  # 4     32/87=4
print(c.itemsize)  # 4
ndarray元素数据类型

在这里插入图片描述

2. 创建ndarray对象
方法一:从组合数据类型中创建

我们只要把列表或者元组这样的python自带的组合数据类型当作np.array()的参数,那么np.array()就会返回一个ndarray对象。即:

a = np.array(list)
b = np.array(tuple)

只要列表和元组同型,那么列表和元组就可以混合使用。
np.array()还有一个参数用来指定数据类型:

a = np.array(list,dtype=np.int32)
b = np.array(tuple,dtype=np.float32)

np.array()dtype参数为空时,np会根据数据情况自动关联一个dtype类型。

>>> a = [1,2,3]
>>> b = np.array(a)
>>> b #ndarray会以array()的形式展现数据
array([1, 2, 3])
>>> a = [[1,2],[3,4]]
>>> b = np.array(a)
>>> b #ndarray在展现数据时会体现数据的维度
array([[1, 2],
       [3, 4]])
方法二:使用np函数创建

在这里插入图片描述

>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.ones((3,6)) #np.ones()的元素默认float64
array([[1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.]])
>>> np.ones((3,6),dtype=np.int32) #生成函数中也可以配置dtype参数
array([[1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1]])
>>> np.zeros((3,6))
array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]])
>>> np.eye(5)
array([[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.]])
>>> a = np.ones((2,3,4))
>>> print(a) #用print输出没有了array的前缀
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
>>> a.shape
(2, 3, 4)
>>> f = np.full((3, 3), 5)
>>> print(f)
[[5 5 5]
 [5 5 5]
 [5 5 5]]

np还有一些根据已有的ndarray类型创建新的ndarray对象的函数:
在这里插入图片描述

>>> a = np.array([[1, 2], [3, 4]])
>>> np.ones_like(a)
array([[1, 1],
       [1, 1]])
>>> np.full_like(a,2233)
array([[2233, 2233],
       [2233, 2233]])

np.linspace()

np.linspace(start, stop, num=50, endpoint=True, 
retstep=False, dtype=None, axis=0)
  • start:返回样本数据开始点
  • stop:返回样本数据结束点
  • num:生成的样本数据量,默认为50
  • endpoint:布尔型参数。True则包含stop;False则不包含stop
  • retstep:布尔型参数。如果为True则结果会给出数据间隔
  • dtype:输出数组类型
  • axis:0(默认)或-1
>>> np.linspace(2.0, 3.0, num=5)
    array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])
>>> np.linspace(2.0, 3.0, num=5, endpoint=False)
    array([ 2. ,  2.2,  2.4,  2.6,  2.8])
>>> np.linspace(2.0, 3.0, num=5, retstep=True)
    (array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25

np.concatenate()

np.concatenate()还有一个axis参数,表示合并地方向,默认为0,表示按第一个维度地方向合并。以矩阵为例,列方向为axis=0,也就是0轴的方向,行方向是1轴的方向。为什么这么规定呢?我们可以认为矩阵是列向量的衍生,而列向量不是只有列吗?所以列向量只有列方向,我们把列向量仅有的方向规定为0轴也就很自然了。当列向量延伸到矩阵时我们保留了0轴的规定,而多出来的行方向我们就用0+1,也就是1轴来规定。

>>> a = np.ones((2,2))
>>> b = np.zeros((2,2))
>>> np.concatenate((a,b)) # axis默认为0
array([[1., 1.],
       [1., 1.],
       [0., 0.],
       [0., 0.]])
>>> np.concatenate((a,b),axis=0) # 按列合并
array([[1., 1.],
       [1., 1.],
       [0., 0.],
       [0., 0.]])
>>> np.concatenate((a,b),axis=1) # 按行合并
array([[1., 1., 0., 0.],
       [1., 1., 0., 0.]])
3. 维度变换函数

np提供了一些进行维度变换的函数,不过它们都是以ndarray对象的方法的形式使用的。使用这些方法可以快速地对我们的数据在维度组织形式上进行塑形。让数据变成我们希望的“形状”。
在这里插入图片描述

>>> a = np.array([1,2,3,4,5,6,7,8,9])
>>> a.reshape((3,3))
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.resize((3,3))
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a.swapaxes(0,1) #交换0轴和1轴方向的维度
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a.flatten()
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
4. 数据类型转换函数

前面提到过ndarray对象的数据部分是有数据类型的。np提供了一个用来对已经存在的ndarray对象进行数据类型转换的函数:new_a = a.astype(new_type)。它会根据new_type返回一个新的数组(ndarray对象)

>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a.dtype
dtype('int32')
>>> b = a.astype(np.float32) #.astype()方法不改变原数组
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> b
array([[1., 2., 3.],
       [4., 5., 6.],
       [7., 8., 9.]], dtype=float32)

我们可以把列表通过np.array()转换成ndarray对象,那反过来怎么把处理好的ndarray对象重新变回列表呢,直接给出函数:ls = a.tolist()

>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a.tolist()
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

(二)数据的索引和切片

Python对数据的索引和切片是非常重要的特征之一,np也继承了传统Python对组合数据类型的切片与索引操作。方法大同小异。

1. 一维数组索引与切片
>>> a = np.array([9,8,7,6,5])
>>> a[2] # 索引,直接可以通过下标索引
7
>>> a[1 : 4 : 2] # 切片,和列表一样,格式为ls[起始编号 : 终止编号(不含) : 步长]
array([8, 6])
2. 多维数组索引与切片
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> a[2,2] # 多维支持a[ax1,ax2,...,axn]的索引,这种方法比较常用
9
>>> a[2][2] # 也支持传统列表a[ax1][ax2]...[axn]的索引方式,不常用
9
>>> a[:2,:2] # 把每个坐标替换成切片操作符就可以分别对每一个维度进行切片了
array([[1, 2],
       [4, 5]])
>>> a[::2,::2] # 切片,和列表一样,格式为ls[起始编号 : 终止编号(不含) : 步长]
array([[1, 3],
       [7, 9]])
>>> a[::-1,::-1]
array([[9, 8, 7],
       [6, 5, 4],
       [3, 2, 1]])

(三)数组运算

1. 标量运算

用标量(实数)去和ndarray对象做加减乘除就是用标量去和数组中的每一个元素做加减乘除。这实际上是ndarray广播运算机制的一种体现。

>>> a = np.arange(24).reshape((2,3,4))
>>> a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],[[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
>>> a + 1000
array([[[1000, 1001, 1002, 1003],
        [1004, 1005, 1006, 1007],
        [1008, 1009, 1010, 1011]],[[1012, 1013, 1014, 1015],
        [1016, 1017, 1018, 1019],
        [1020, 1021, 1022, 1023]]])
>>> a * 3.14
array([[[ 0.  ,  3.14,  6.28,  9.42],
        [12.56, 15.7 , 18.84, 21.98],
        [25.12, 28.26, 31.4 , 34.54]],[[37.68, 40.82, 43.96, 47.1 ],
        [50.24, 53.38, 56.52, 59.66],
        [62.8 , 65.94, 69.08, 72.22]]])
>>> a.mean()
11.5
>>> a / a.mean()
array([[[0.        , 0.08695652, 0.17391304, 0.26086957],
        [0.34782609, 0.43478261, 0.52173913, 0.60869565],
        [0.69565217, 0.7826087 , 0.86956522, 0.95652174]],[[1.04347826, 1.13043478, 1.2173913 , 1.30434783],
        [1.39130435, 1.47826087, 1.56521739, 1.65217391],
        [1.73913043, 1.82608696, 1.91304348, 2.        ]]])
2. 一元函数

np提供了一些一元函数来对数组中的每一个元素进行计算:(操作对象:单个ndarray对象)
在这里插入图片描述

3. 二元函数

np提供了一些函数与操作符来对两个ndarray对象进行操作:
在这里插入图片描述

>>> 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]])
>>> b = np.sqrt(a)
>>> b
array([[0.        , 1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974, 2.64575131],
       [2.82842712, 3.        , 3.16227766, 3.31662479],
       [3.46410162, 3.60555128, 3.74165739, 3.87298335]])
>>> np.maximum(a,b)
array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.],
       [12., 13., 14., 15.]])
>>> a > b
array([[False, False,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True],
       [ True,  True,  True,  True]])
4. 线性代数库

np提供了线性代数函数库 linalg,该库包含了线性代数所需的几乎所有功能
在这里插入图片描述

(四)随机数

1. 基础np随机数生成函数

numpy有一个random子库,用法与python原本的random库差不多,调用时记得加上random:np.random.<方法>

在这里插入图片描述

>>> np.random.rand(3,3) #生成一个3*3的随机数矩阵
array([[0.28034402, 0.7632137 , 0.77616993],
       [0.67435242, 0.17635725, 0.48415525],
       [0.6530347 , 0.33255404, 0.44074308]])
>>> np.random.randn(3,3) #矩阵元素符合正态分布
array([[ 0.19233304,  0.85012517,  1.17034056],
       [-0.30448713, -2.2180847 , -0.09353092],
       [ 0.5803468 ,  0.59346808, -0.60543587]])
>>> np.random.randint(0,10,(3,3)) #每个元素都是范围在[0,10)的随机整数
array([[0, 1, 3],
       [7, 5, 5],
       [0, 9, 1]])
>>> np.random.seed(10) #通过设定同一个随机数种子,可以使得生成的随机数完全相同
>>> np.random.randint(100,200,(3,4))
array([[109, 115, 164, 128],
       [189, 193, 129, 108],
       [173, 100, 140, 136]])
>>> np.random.randint(100,200,(3,4))
array([[116, 111, 154, 188],
       [162, 133, 172, 178],
       [149, 151, 154, 177]])
>>> np.random.seed(10)
>>> np.random.randint(100,200,(3,4))
array([[109, 115, 164, 128],
       [189, 193, 129, 108],
       [173, 100, 140, 136]])
2. np的高级随机数函数

在这里插入图片描述

>>> a = np.random.randint(100,200,(3,4))
>>> a
array([[116, 111, 154, 188],
       [162, 133, 172, 178],
       [149, 151, 154, 177]])
>>> np.random.shuffle(a) #只对a的第一个轴(0轴,即axis=0)洗牌
>>> a
array([[116, 111, 154, 188],
       [149, 151, 154, 177],
       [162, 133, 172, 178]]) 
>>> np.random.shuffle(a) #我们洗了两次牌,可以看到只有列方向的三个元素之间交换了元素
>>> a
array([[162, 133, 172, 178],
       [116, 111, 154, 188],
       [149, 151, 154, 177]])
3. 概率分布函数

在这里插入图片描述

>>> a = np.random.uniform(0,10,(3,4))
>>> a
array([[3.7334076 , 6.74133615, 4.41833174, 4.34013993],
       [6.17766978, 5.13138243, 6.50397182, 6.01038953],
       [8.05223197, 5.21647152, 9.08648881, 3.19236089]])
>>> a = np.random.normal(10,5,(3,4))
>>> a
array([[ 8.66341406,  7.25345493, 10.66354148,  7.61928993],
       [16.5423654 , 10.9750664 , 12.00104994,  8.31183831],
       [16.28236132,  6.34015249, 13.30115776,  8.24564054]])

(五)统计函数与梯度函数

1. 统计函数

以下几乎所有涉及的函数都有其对应的方法版,比如:

a = np.array([1,2,3])
print(max(a))
print(a.max())

在这里插入图片描述
以矩阵为例,列的方向就是axis=0(0轴,也就是所谓的第一个轴)的方向。那么以axis=0的方向对矩阵使用max就是求矩阵每个列向量中元素的最大值:

>>> a = np.arange(1,10,1).reshape((3,3))
>>> a
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> np.max(a) # 全局最大值
9
>>> np.max(a,axis=0) # 0轴方向,也就是1,4,7方向
array([7, 8, 9])
>>> np.max(a,axis=1) # 1轴方向,也就是1,2,3方向
array([3, 6, 9])
>>> a = np.random.randint(1,100,(3,3))
>>> a
array([[93, 97, 63],
       [58, 80, 43],
       [58, 98, 51]])
>>> np.sum(a)
641
>>> a.sum() # 结果方法版我还是展示了
641
>>> np.sum(a,axis=0)
array([209, 275, 157])
>>> np.sum(a,axis=1)
array([253, 181, 207])
>>> np.mean(a,axis=0)
array([69.66666667, 91.66666667, 52.33333333])
>>> np.mean(a,axis=1)
array([84.33333333, 60.33333333, 69.        ])
>>> np.average(a,axis=0,weights=[10,5,1])
array([79.875, 91.75 , 56.   ]) # 79.875 = (10 * 93 + 5 * 58 + 1 * 58) / (10 + 5 + 1)
>>> np.std(a)
19.87615979999813
>>> np.var(a)
395.0617283950617
>>> a
array([[93, 97, 63],
       [58, 80, 43],
       [58, 98, 51]])
>>> np.max(a)
98
>>> np.argmax(a) # 扁平化的下标
7
>>> np.argmax(a,axis=0)
array([0, 2, 0], dtype=int64)
>>> np.ptp(a)
55
>>> np.ptp(a,axis=0) # 机器学习的样本预处理经常要对axis=0的元素求ptp
array([35, 18, 20])
>>> np.median(a)
63.0
2. 梯度函数

在这里插入图片描述

>>> a = np.random.randint(0,20,(5,))
>>> a
array([13,  8,  9,  5,  0])
>>> np.gradient(a) #中间的第i个元素的梯度=(a[i + 1] - a[i - 1]) / 2,最后一个元素a[n]的梯度=(a[n] - a[n - 1]) / 1,第一个元素a[0]的梯度=(a[1] - a[0]) / 1
array([-5. , -2. , -1.5, -4.5, -5. ]) 
>>> a = np.random.randint(0,20,(5,)) # 再给一组感觉感觉
>>> a
array([18,  3, 16, 18, 16])
>>> np.gradient(a)
array([-15. ,  -1. ,   7.5,   0. ,  -2. ])
>>> b = np.random.randint(0,50,(3,5))
>>> b
array([[14, 15, 17, 25, 46],
       [48, 42, 17, 32, 17],
       [41, 16, 41, 26, 12]])
>>> np.gradient(b)
[array([[ 34. ,  27. ,   0. ,   7. , -29. ], # 第一个维度axis=0方向的梯度(列方向)
       [ 13.5,   0.5,  12. ,   0.5, -17. ],
       [ -7. , -26. ,  24. ,  -6. ,  -5. ]]), 
 array([[  1. ,   1.5,   5. ,  14.5,  21. ], # 第二个维度axis=1方向的梯度(行方向)
       [ -6. , -15.5,  -5. ,   0. , -15. ], 
       [-25. ,   0. ,   5. , -14.5, -14. ]])]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值