NumPy入门讲座(1):基本概念_numpy数据相关概念-程序员宅基地

技术标签: 跟“风云卫星”数据工程师学Python  python  数据分析  机器学习  人工智能  

1. NumPy 的家族

NumPy 是 SciPy 家族的一员,而且是最重要的成员。SciPy 家族(见下图)是一个专门应用于数学、科学和工程领域的开源的 Python 生态圈。NumPy 最初是 SciPy 的一部分,后来独立出来了。SciPy 家族的主体,可以概括为 MSN 这三个字母,你要是喜欢足球的话,一定会联想到巴萨的梅西、苏亚雷斯和内马尔这个MSN三剑客组合。我喜欢把 Matplotlib、SciPy 和 NumPy 叫做 MSN 组合,并专门写了一篇博文,名字就叫《数学建模三剑客MSN》
在这里插入图片描述

NumPy 的安装,非常简单,直接使用 pip 命令安装即可。通常,安装 NumPy 的时候,也会顺便安装 SciPy 模块、matplotlib 模块。

PS D:>python –m pip install numpy
PS D:>python –m pip install scipy
PS D:>python –m pip install matplotlib

使用 NumPy 时,我们习惯把它简写成 np。提醒大家注意:pip 命令需要在命令行窗口中运行,而不是在下图所示的 IDEL 窗口中。 在 IDEL 窗口中可以交互式执行 Python 语句,是学习 Python 的有力工具。
在这里插入图片描述

2. NumPy 是数据处理和科学计算的基础

NumPy 是 Python 科学计算的基础软件包,提供多了维数组对象,多种派生对象(掩码数组、矩阵等)以及用于快速操作数组的函数及 API,它包括数学、逻辑、数组形状变换、排序、选择、I/O 、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等等。

和 Python 的列表相比,NumPy 拥有明显的速度优势。NumPy 底层使用 C 语言编写,内置了并行运算功能,并且内部解除了 GIL(全局解释器锁)。这意味着:

  • 其对数组的操作速度不受 Python 解释器的限制
  • 当系统有多个 CPU 时,NumPy 可以自动并行计算

NumPy 的数据组织结构,尤其是数组(numpy.ndarray),几乎已经成为所有数据处理与机器学习的标准数据结构了。越来越多的基于 Python 的机器学习和数据处理软件包使用 NumPy 数组,虽然这些工具通常都支持 Python 的原生数组(即列表——在不冲突的前提下,我可能会混用数组和列表)作为参数,但它们在处理之前会还是会将输入的数组转换为 NumPy 数组,而且也通常输出为 NumPy 数组。在 Python 的圈子里,NumPy 的重要性和普遍性日趋增强。换句话说,为了高效地使用当今机器学习和数据处理等基于 Python 的工具包,你只知道如何使用 Python 的原生数组是不够的,还需要知道如何使用 NumPy 数组。
在这里插入图片描述
上面这一张图,展示的是 Python 旗下用于图像视觉处理、2D绘图、3D渲染、数据处理、机器学习等领域比较有名的5个工具模块,都深度依赖 NumPy 数组。可以说,没有NumPy的基础,任何人都很难用好上述这5个工具库。

  • OpenCV:目前以人脸识别、自动驾驶等技术为代表的人工智能方兴未艾,其背后的图像和视觉处理,几乎都离不开 OpenCV,而 OpenCV 库中图像的数据结构,从 CV2 之后,全面转向了 NumPy,用 OpenCV 打开图像文件,得到的就是 NumPy 数组
  • OpenGL:在三维领域大名鼎鼎的OpenGL,更是深度依赖NumPy,如果没有NumPy,我们无法想象如何操作动辄几万、几十万,甚至几百万的顶点数据集
  • Pandas:这个是当下非常流行的数据分析工具包,相信很多人都是从Pandas开始接触数据处理的,而Pandas整个就是基于NumPy之上的扩展
  • Matplotlib:作为NumPy生态圈的重要成员,二者关系自然是密不可分的
  • scikit-learn:机器学习领域应用最广泛的工具包,则是建立在NumPy/SciPy/Matplotlib之上的,同样深度依赖NumPy

3. NumPy 数组 VS Python 列表

学过 Python 的同学都知道,Python 的列表操作非常灵活,而 NumPy 数组继承了 Python 数组操作便捷、灵活的特点,又具有极高的、接近 C 语言的运行效率。可以说,NumPy 数组是专为处理科学数据而生的。

  • NumPy 数组中的元素必须具有相同的数据类型,Python 列表的元素类型则不受限制;
  • NumPy 数组一旦创建,其元素数量不可再改变,Python 列表的元素则可以动态增减;
  • NumPy 数组和 Python 同样操作简单、灵活,但前者内置方法更多、运行速度更快。

4. NumPy 数组的数据类型

NumPy 支持的数据类型主要有整型(integrate)、浮点型(float)、布尔型(bool)和复数型(complex),每一种数据类型根据占用内存的字节数又分为多个不同的子类型。当然,NumPy 也支持自定义类型,我们在后面讲解数组排序的时候,再讨论自定义类型。
在这里插入图片描述
咱们来演示一下如何查看、指定数据类型。

>>> a = np.array([0,1,2,3])
>>> a.dtype
dtype('int32')
>>> a = np.array([0,1,2,3.0])
>>> a.dtype
dtype('float64')
>>> a = np.array([0,1,2,3+0j])
>>> a.dtype
dtype('complex128')
>>> a = np.array([0,1,2,3], dtype=np.int16)
>>> a.dtype
dtype('int16')
>>> a = np.array([0,1,2,3], dtype=np.uint8)
>>> a.dtype
dtype('uint8')

dtype 是数组的属性之一,可以很方便地查看数组的数据类型。创建数组时,如果不指定数据类型,numpy会根据输入数据选择合适的数据类型。指定数据类型的时候,通常可以省略类型后面的数字。如果省略数字的话,整形和无符号整形默认是32位的,浮点型默认是64位的,复数型默认是128位。

5. NumPy 数组的属性

刚才我们用 dtype 可以查看数组的数据类型,dtype 是数组对象的属性之一,除了 dtype,NumPy 数组还有其他一些属性,比如,shape,数组结构,或者叫形状;sizes,数组元素个数;itemsize,数组元素字节数;flags,数组的内存信息;real,数组实部;imag,数据虚部;data,存储区域内存地址,相当于指针。除此之外,还有一个属性,ndim,数组的维度数,也叫秩,下一节会专门讲它。属性看起来有点多,但我们只需要记住 dtypeshape 两个属性就足够了。这两个属性非常重要,重要到你可以忽略其他的属性。

属性 说明
ndarray.dtype 元素类型
ndarray.shape 数组结构
ndarray.size 元素个数
ndarray.itemsize 每个元素的大小,以字节为单位
ndarray.ndim 数组的维度数,也叫秩
ndarray.flags 数组的内存信息
ndarray.real 元素的实部
ndarray.imag 元素的虚部
ndarray.data 元素数组的实际存储区

下面是这些属性的演示操作:

>>> a = np.arange(24, dtype=np.complex64).reshape((2,3,4))
>>> a.dtype # 复数类型
dtype('complex64')
>>> a.shape # 2层3行4列
(2, 3, 4)
>>> a.size # 总共24个元素
24
>>> a.itemsize # 每个元素占用8个字节
8
>>> a.flags # 存储信息
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

>>> a.real # 实部
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.]]], dtype=float32)
>>> a.imag # 虚部
array([[[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]],

       [[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]]], dtype=float32)
>>> a.data # 内存区域地址
<memory at 0x00000157D820BC78>
>>> a.ndim # 维度数(秩)
3

6. 维、秩、轴

维,就是维度。我们说数组是几维的,就是指维度,3维的数组,其维度数,自然就是3。维度数,有一个专用名字,叫做秩,也就是上一节提到的数组属性 ndim。秩,这个名字感觉有些多余,不如维度数更容易理解。但是,轴的概念,大家一定要建立起来,并且要理解,因为轴的概念很重要。简单来说,我们可以把数组的轴,和笛卡尔坐标系的轴对应一下。

一维数组,类比于一维空间,只有一个轴,那就是0轴。
在这里插入图片描述

二维数组,类比于二维平面,有两个轴,我们习惯表示成行、列,那么行的方向就是0轴,列的方向就是1轴。
在这里插入图片描述
三维数组,类比于三维空间,有三个轴,我们习惯表示成层、行、列,那么层的方向就是0轴,行的方向就是1轴,列的方向就是2轴。
在这里插入图片描述

我们用一个求和的例子来演示一下轴概念的重要性。先来看看用 Python 的求和。

>>> a = [2,5,4,7,9,3] # python的求和函数sum(),只能对一维列表求和
>>> sum(a)
30
>>> a = [[3,5,1],[2,6,9]] # 如果是多维列表,那就会报错了
>>> sum(a)
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    sum(a)
TypeError: unsupported operand type(s) for +: 'int' and 'list'

但有时候,我们的需求会比较复杂,比如,分层求和,逐行求和,逐列求和等。这时候,Numpy 的轴概念就可以大显身手了。

>>> a = np.arange(18).reshape((3,2,3)) # 3层2行3列的结构
>>> a
array([[[ 0,  1,  2],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]],

       [[12, 13, 14],
        [15, 16, 17]]])
>>> np.sum(a)
153 
>>> np.sum(a, axis=0) # 层合并求和
array([[18, 21, 24],
       [27, 30, 33]])
>>> np.sum(a, axis=1) # 行合并求和
array([[ 3,  5,  7],
       [15, 17, 19],
       [27, 29, 31]])
>>> np.sum(a, axis=2) # 列合并求和
array([[ 3, 12],
       [21, 30],
       [39, 48]])
>>> np.sum(np.sum(a, axis=1), axis=1) # 分层求和方法1
array([15, 51, 87])
>>> np.sum(np.sum(a, axis=2), axis=1) # 分层求和方法2
array([15, 51, 87])

同样是求和,显然,NumPy数组要比Python列表更强大、更灵活。

7. 广播和矢量化

在讲两个概念之前,我们先思考两个问题:

  1. 整型数组各元素加1;
  2. 求两个等长整型数组对应元素之和组成的新数组。

我们先用python数组实现:

>>> x = list(range(5))
>>> for i in range(len(x)): # 遍历数组为每个元素加1
        x[i] += 1
>>> y = list(range(5,10))
>>> z = list()
>>> for i, j in zip(x, y): # 遍历两个数组,逐个元素求和
        z.append(i+j)

我们再用NumPy数组实现:

>>> a = np.arange(5)
>>> a += 1
>>> b = np.arange(5,10)
>>> c = a + b

显然,用NumPy数组实现起来,要比python数组更简洁、更清晰。这得益于于 NumPy 的两大特性:广播(broadcast)和矢量化(vectorization)。

广播和矢量化,是 NumPy 最精髓的特性,是 NumPy 的灵魂。所谓广播,就是将对数组的操作映射到每个数组元素上;矢量化可以理解为代码中没有显式的循环、索引等。NumPy数组最重要的特性是广播和矢量化,体现在性能上,就是接近C语言的运行效率,体现在代码上,则有这样的特点:

  1. 矢量化代码更简洁,更易于阅读;
  2. 代码行越少意味着出错的几率越小;
  3. 代码更接近于标准的数学符号;
  4. 矢量化代码更pythonic

在这里插入图片描述

后记

近期有很多朋友通过私信咨询有关Python学习问题。为便于交流,我在CSDN的app上创建了“Python作业辅导”大本营,面向Python初学者,为大家提供咨询服务、辅导Python作业。欢迎有兴趣的同学使用微信扫码加入。

在这里插入图片描述

从博客到公众号,每一篇、每一题、每一句、每一行代码,都坚持原创,绝不复制抄袭,这是我坚守的原则。如果喜欢,请关注我的微信公众号“Python作业辅导员”。

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xufive/article/details/103567312

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue

推荐文章

热门文章

相关标签