江西门户网站建设,seo网站排名查询,安卓安装wordpress,衡水 网站开发Numpy基础应用
Numpy 是一个开源的 Python 科学计算库#xff0c;用于快速处理任意维度的数组。Numpy 支持常见的数组和矩阵操作#xff0c;对于同样的数值计算任务#xff0c;使用 NumPy 不仅代码要简洁的多#xff0c;而且 NumPy 的性能远远优于原生 Python#xff0c;…Numpy基础应用
Numpy 是一个开源的 Python 科学计算库用于快速处理任意维度的数组。Numpy 支持常见的数组和矩阵操作对于同样的数值计算任务使用 NumPy 不仅代码要简洁的多而且 NumPy 的性能远远优于原生 Python基本是一个到两个数量级的差距而且数据量越大NumPy 的优势就越明显。
Numpy 最为核心的数据类型是ndarray使用ndarray可以处理一维、二维和多维数组该对象相当于是一个快速而灵活的大数据容器。NumPy 底层代码使用 C 语言编写解决了 GIL 的限制ndarray在存取数据的时候数据与数据的地址都是连续的这确保了可以进行高效率的批量操作远远优于 Python 中的list另一方面ndarray对象提供了更多的方法来处理数据尤其是和统计相关的方法这些方法也是 Python 原生的list没有的。
全部文章请访问专栏《Python全栈教程0基础》 再推荐一下最近热更的《大厂测试高频面试题详解》 该专栏对近年高频测试相关面试题做详细解答结合自己多年工作经验以及同行大佬指导总结出来的。旨在帮助测试、python方面的同学顺利通过面试拿到自己满意的offer 文章目录 Numpy基础应用准备工作创建数组对象一维数组二维数组多维数组 数组对象的属性数组的索引和切片案例通过数组切片处理图像 数组对象的方法统计方法其他方法 准备工作 启动Notebook jupyter notebook提示在启动Notebook之前建议先安装好数据分析相关依赖项包括之前提到的三大神器以及相关依赖项包括numpy、pandas、matplotlib、openpyxl等。如果使用Anaconda则无需单独安装。 导入 import numpy as np
import pandas as pd
import matplotlib.pyplot as plt说明如果已经启动了 Notebook 但尚未安装相关依赖库例如尚未安装numpy可以在 Notebook 的单元格中输入!pip install numpy并运行该单元格来安装 NumPy也可以一次性安装多个三方库需要在单元格中输入%pip install numpy pandas matplotlib。注意上面的代码我们不仅导入了NumPy还将 pandas 和 matplotlib 库一并导入了。
创建数组对象
创建ndarray对象有很多种方法下面就如何创建一维数组、二维数组和多维数组进行说明。
一维数组 方法一使用array函数通过list创建数组对象 代码 array1 np.array([1, 2, 3, 4, 5])
array1输出 array([1, 2, 3, 4, 5])方法二使用arange函数指定取值范围创建数组对象 代码 array2 np.arange(0, 20, 2)
array2输出 array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])方法三使用linspace函数用指定范围均匀间隔的数字创建数组对象 代码 array3 np.linspace(-5, 5, 101)
array3输出 array([-5. , -4.9, -4.8, -4.7, -4.6, -4.5, -4.4, -4.3, -4.2, -4.1, -4. ,-3.9, -3.8, -3.7, -3.6, -3.5, -3.4, -3.3, -3.2, -3.1, -3. , -2.9,-2.8, -2.7, -2.6, -2.5, -2.4, -2.3, -2.2, -2.1, -2. , -1.9, -1.8,-1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1. , -0.9, -0.8, -0.7,-0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0. , 0.1, 0.2, 0.3, 0.4,0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4, 1.5,1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6,2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7,3.8, 3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8,4.9, 5. ])方法四使用numpy.random模块的函数生成随机数创建数组对象 产生10个 [ 0 , 1 ) [0, 1) [0,1)范围的随机小数代码 array4 np.random.rand(10)
array4输出 array([0.45556132, 0.67871326, 0.4552213 , 0.96671509, 0.44086463,0.72650875, 0.79877188, 0.12153022, 0.24762739, 0.6669852 ])产生10个 [ 1 , 100 ) [1, 100) [1,100)范围的随机整数代码 array5 np.random.randint(1, 100, 10)
array5输出 array([29, 97, 87, 47, 39, 19, 71, 32, 79, 34])产生20个 μ 50 \mu50 μ50 σ 10 \sigma10 σ10的正态分布随机数代码 array6 np.random.normal(50, 10, 20)
array6输出 array([55.04155586, 46.43510797, 20.28371158, 62.67884053, 61.23185964,38.22682148, 53.17126151, 43.54741592, 36.11268017, 40.94086676,63.27911699, 46.92688903, 37.1593374 , 67.06525656, 67.47269463,23.37925889, 31.45312239, 48.34532466, 55.09180924, 47.95702787])说明创建一维数组还有很多其他的方式比如通过读取字符串、读取文件、解析正则表达式等方式这里我们暂不讨论这些方式有兴趣的读者可以自行研究。 二维数组 方法一使用array函数通过嵌套的list创建数组对象 代码 array7 np.array([[1, 2, 3], [4, 5, 6]])
array7输出 array([[1, 2, 3],[4, 5, 6]])方法二使用zeros、ones、full函数指定数组的形状创建数组对象 使用zeros函数代码 array8 np.zeros((3, 4))
array8输出 array([[0., 0., 0., 0.],[0., 0., 0., 0.],[0., 0., 0., 0.]])使用ones函数代码 array9 np.ones((3, 4))
array9输出 array([[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]])使用full函数代码 array10 np.full((3, 4), 10)
array10输出 array([[10, 10, 10, 10],[10, 10, 10, 10],[10, 10, 10, 10]])方法三使用eye函数创建单位矩阵 代码 array11 np.eye(4)
array11输出 array([[1., 0., 0., 0.],[0., 1., 0., 0.],[0., 0., 1., 0.],[0., 0., 0., 1.]])方法四通过reshape将一维数组变成二维数组 代码 array12 np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3)
array12输出 array([[1, 2, 3],[4, 5, 6]])提示reshape是ndarray对象的一个方法使用reshape方法时需要确保调形后的数组元素个数与调形前数组元素个数保持一致否则将会产生异常。 方法五通过numpy.random模块的函数生成随机数创建数组对象 产生 [ 0 , 1 ) [0, 1) [0,1)范围的随机小数构成的3行4列的二维数组代码 array13 np.random.rand(3, 4)
array13输出 array([[0.54017809, 0.46797771, 0.78291445, 0.79501326],[0.93973783, 0.21434806, 0.03592874, 0.88838892],[0.84130479, 0.3566601 , 0.99935473, 0.26353598]])产生 [ 1 , 100 ) [1, 100) [1,100)范围的随机整数构成的3行4列的二维数组代码 array14 np.random.randint(1, 100, (3, 4))
array14输出 array([[83, 30, 64, 53],[39, 92, 53, 43],[43, 48, 91, 72]])多维数组 使用随机的方式创建多维数组 代码 array15 np.random.randint(1, 100, (3, 4, 5))
array15输出 array([[[94, 26, 49, 24, 43],[27, 27, 33, 98, 33],[13, 73, 6, 1, 77],[54, 32, 51, 86, 59]],[[62, 75, 62, 29, 87],[90, 26, 6, 79, 41],[31, 15, 32, 56, 64],[37, 84, 61, 71, 71]],[[45, 24, 78, 77, 41],[75, 37, 4, 74, 93],[ 1, 36, 36, 60, 43],[23, 84, 44, 89, 79]]])将一维二维的数组调形为多维数组 一维数组调形为多维数组代码 array16 np.arange(1, 25).reshape((2, 3, 4))
array16输出 array([[[ 1, 2, 3, 4],[ 5, 6, 7, 8],[ 9, 10, 11, 12]],[[13, 14, 15, 16],[17, 18, 19, 20],[21, 22, 23, 24]]])二维数组调形为多维数组代码 array17 np.random.randint(1, 100, (4, 6)).reshape((4, 3, 2))
array17输出 array([[[60, 59],[31, 80],[54, 91]],[[67, 4],[ 4, 59],[47, 49]],[[16, 4],[ 5, 71],[80, 53]],[[38, 49],[70, 5],[76, 80]]])读取图片获得对应的三维数组 代码 array18 plt.imread(guido.jpg)
array18输出 array([[[ 36, 33, 28],[ 36, 33, 28],[ 36, 33, 28],...,[ 32, 31, 29],[ 32, 31, 27],[ 31, 32, 26]],[[ 37, 34, 29],[ 38, 35, 30],[ 38, 35, 30],...,[ 31, 30, 28],[ 31, 30, 26],[ 30, 31, 25]],[[ 38, 35, 30],[ 38, 35, 30],[ 38, 35, 30],...,[ 30, 29, 27],[ 30, 29, 25],[ 29, 30, 25]],...,[[239, 178, 123],[237, 176, 121],[235, 174, 119],...,[ 78, 68, 56],[ 75, 67, 54],[ 73, 65, 52]],[[238, 177, 120],[236, 175, 118],[234, 173, 116],...,[ 82, 70, 58],[ 78, 68, 56],[ 75, 66, 51]],[[238, 176, 119],[236, 175, 118],[234, 173, 116],...,[ 84, 70, 61],[ 81, 69, 57],[ 79, 67, 53]]], dtypeuint8)说明上面的代码读取了当前路径下名为guido.jpg 的图片文件计算机系统中的图片通常由若干行若干列的像素点构成而每个像素点又是由红绿蓝三原色构成的所以能够用三维数组来表示。读取图片用到了matplotlib库的imread函数。
数组对象的属性 size属性数组元素个数 代码 array19 np.arange(1, 100, 2)
array20 np.random.rand(3, 4)
print(array19.size, array20.size)输出 50 12shape属性数组的形状 代码 print(array19.shape, array20.shape)输出 (50,) (3, 4)dtype属性数组元素的数据类型 代码 print(array19.dtype, array20.dtype)输出 int64 float64ndarray对象元素的数据类型可以参考如下所示的表格。 ndim属性数组的维度 代码 print(array19.ndim, array20.ndim)输出 1 2itemsize属性数组单个元素占用内存空间的字节数 代码 array21 np.arange(1, 100, 2, dtypenp.int8)
print(array19.itemsize, array20.itemsize, array21.itemsize)输出 8 8 1说明在使用arange创建数组对象时通过dtype参数指定元素的数据类型。可以看出np.int8代表的是8位有符号整数只占用1个字节的内存空间取值范围是 [ − 128 , 127 ] [-128,127] [−128,127]。 nbytes属性数组所有元素占用内存空间的字节数 代码 print(array19.nbytes, array20.nbytes, array21.nbytes)输出 400 96 50flat属性数组一维化之后元素的迭代器 代码 from typing import Iterableprint(isinstance(array20.flat, np.ndarray), isinstance(array20.flat, Iterable))输出 False Truebase属性数组的基对象如果数组共享了其他数组的内存空间 代码 array22 array19[:]
print(array22.base is array19, array22.base is array21)输出 True False说明上面的代码用到了数组的切片操作它类似于 Python 中list类型的切片但在细节上又不完全相同下面会专门讲解这个知识点。通过上面的代码可以发现ndarray切片后得到的新的数组对象跟原来的数组对象共享了内存中的数据因此array22的base属性就是array19对应的数组对象。
数组的索引和切片
和 Python 中的列表类似NumPy 的ndarray对象可以进行索引和切片操作通过索引可以获取或修改数组中的元素通过切片可以取出数组的一部分。 索引运算普通索引 一维数组代码 array23 np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(array23[0], array23[array23.size - 1])
print(array23[-array23.size], array23[-1])输出 1 9
1 9二维数组代码 array24 np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array24[2])
print(array24[0][0], array24[-1][-1])
print(array24[1][1], array24[1, 1])输出 [7 8 9]
1 9
5 5
[[ 1 2 3][ 4 10 6][ 7 8 9]]代码 array24[1][1] 10
print(array24)
array24[1] [10, 11, 12]
print(array24)输出 [[ 1 2 3][ 4 10 6][ 7 8 9]]
[[ 1 2 3][10 11 12][ 7 8 9]]切片运算切片索引 切片是形如[开始索引:结束索引:步长]的语法通过指定开始索引默认值无穷小、结束索引默认值无穷大和步长默认值1从数组中取出指定部分的元素并构成新的数组。因为开始索引、结束索引和步长都有默认值所以它们都可以省略如果不指定步长第二个冒号也可以省略。一维数组的切片运算跟 Python 中的list类型的切片非常类似此处不再赘述二维数组的切片可以参考下面的代码相信非常容易理解。 代码 print(array24[:2, 1:])输出 [[2 3][5 6]]代码 print(array24[2])
print(array24[2, :])输出 [7 8 9]
[7 8 9]代码 print(array24[2:, :])输出 [[7 8 9]]代码 print(array24[:, :2])输出 [[1 2][4 5][7 8]]代码 print(array24[1, :2])
print(array24[1:2, :2])输出 [4 5]
[[4 5]]代码 print(array24[::2, ::2])输出 [[1 3][7 9]]代码 print(array24[::-2, ::-2])输出 [[9 7][3 1]]关于数组的索引和切片运算大家可以通过下面的两张图来增强印象这两张图来自《利用Python进行数据分析》一书它是pandas库的作者 Wes McKinney 撰写的 Python 数据分析领域的经典教科书有兴趣的读者可以购买和阅读原书。 花式索引fancy index 花式索引Fancy indexing是指利用整数数组进行索引这里所说的整数数组可以是 NumPy 的ndarray也可以是 Python 中list、tuple等可迭代类型可以使用正向或负向索引。 一维数组的花式索引代码 array25 np.array([50, 30, 15, 20, 40])
array25[[0, 1, -1]]输出 array([50, 30, 40])二维数组的花式索引代码 array26 np.array([[30, 20, 10], [40, 60, 50], [10, 90, 80]])
# 取二维数组的第1行和第3行
array26[[0, 2]]输出 array([[30, 20, 10],[10, 90, 80]])代码 # 取二维数组第1行第2列第3行第3列的两个元素
array26[[0, 2], [1, 2]]输出 array([20, 80])代码 # 取二维数组第1行第2列第3行第2列的两个元素
array26[[0, 2], 1]输出 array([20, 90])布尔索引 布尔索引就是通过布尔类型的数组对数组元素进行索引布尔类型的数组可以手动构造也可以通过关系运算来产生布尔类型的数组。 代码 array27 np.arange(1, 10)
array27[[True, False, True, True, False, False, False, False, True]]输出 array([1, 3, 4, 9])代码 array27 5输出 array([False, False, False, False, True, True, True, True, True])代码 # ~运算符可以实现逻辑变反看看运行结果跟上面有什么不同
~(array27 5)输出 array([ True, True, True, True, False, False, False, False, False])代码 array27[array27 5]输出 array([5, 6, 7, 8, 9])提示切片操作虽然创建了新的数组对象但是新数组和原数组共享了数组中的数据简单的说如果通过新数组对象或原数组对象修改数组中的数据其实修改的是同一块数据。花式索引和布尔索引也会创建新的数组对象而且新数组复制了原数组的元素新数组和原数组并不是共享数据的关系这一点通过前面讲的数组的base属性也可以了解到在使用的时候要引起注意。 案例通过数组切片处理图像
学习基础知识总是比较枯燥且没有成就感的所以我们还是来个案例为大家演示下上面学习的数组索引和切片操作到底有什么用。前面我们说到过可以用三维数组来表示图像那么通过图像对应的三维数组进行操作就可以实现对图像的处理如下所示。
读入图片创建三维数组对象。
guido_image plt.imread(guido.jpg)
plt.imshow(guido_image)对数组的0轴进行反向切片实现图像的垂直翻转。
plt.imshow(guido_image[::-1])对数组的1轴进行反向切片实现图像的水平翻转。
plt.imshow(guido_image[:,::-1])将 Guido 的头切出来。
plt.imshow(guido_image[30:350, 90:300])数组对象的方法
统计方法
统计方法主要包括sum()、mean()、std()、var()、min()、max()、argmin()、argmax()、cumsum()等分别用于对数组中的元素求和、求平均、求标准差、求方差、找最大、找最小、求累积和等请参考下面的代码。
array28 np.array([1, 2, 3, 4, 5, 5, 4, 3, 2, 1])
print(array28.sum())
print(array28.mean())
print(array28.max())
print(array28.min())
print(array28.std())
print(array28.var())
print(array28.cumsum())输出
30
3.0
5
1
1.4142135623730951
2.0
[ 1 3 6 10 15 20 24 27 29 30]其他方法 all() / any()方法判断数组是否所有元素都是True / 判断数组是否有为True的元素。 astype()方法拷贝数组并将数组中的元素转换为指定的类型。 dump()方法保存数组到文件中可以通过 NumPy 中的load()函数从保存的文件中加载数据创建数组。 代码 array31.dump(array31-data)
array32 np.load(array31-data, allow_pickleTrue)
array32输出 array([[1, 2],[3, 4],[5, 6]])fill()方法向数组中填充指定的元素。 flatten()方法将多维数组扁平化为一维数组。 代码 array32.flatten()输出 array([1, 2, 3, 4, 5, 6])nonzero()方法返回非0元素的索引。 round()方法对数组中的元素做四舍五入操作。 sort()方法对数组进行就地排序。 代码 array33 np.array([35, 96, 12, 78, 66, 54, 40, 82])
array33.sort()
array33输出 array([12, 35, 40, 54, 66, 78, 82, 96])swapaxes()和transpose()方法交换数组指定的轴。 代码 # 指定需要交换的两个轴顺序无所谓
array32.swapaxes(0, 1)输出 array([[1, 3, 5],[2, 4, 6]])代码 # 对于二维数组transpose相当于实现了矩阵的转置
array32.transpose()输出 array([[1, 3, 5],[2, 4, 6]])tolist()方法将数组转成Python中的list。