Python Numpy简介

原文地址:What is Numpy?

Numpy是应用Python进行科学计算时的基础模块。它是一个提供多维数组对象的Python库,除此之外,还包含了多种衍生的对象(比如掩码式数组(masked arrays)或矩阵)以及一系列的为快速计算数组而生的例程,包括数学运算,逻辑运算,形状操作,排序,选择,I/O,离散傅里叶变换,基本线性代数,基本统计运算,随机模拟等等。

Numpy库中最核心的部分是ndarray 对象。它封装了同构数据类型的n维数组,它的功能将通过演示代码的形式呈现。 NumPy数组和标准Python序列之间有几个重要区别: (1)Numpy数组在创建时就会有一个固定的尺寸,这一点和Python中的list数据类型(可以动态生长)是不同的。当Numpy数组的尺寸发生改变时其实会删除之前的而创建一个新的数组。 (2)在一个Numpy数组中的所有元素数组类型要一致,并在内存中占有相同的大小。这里有一点例外:可以在Python的数组中包含Numpy的对象,这样的话就可以实现不同类型的元素。 (3)在数据量巨大时,使用Numpy进行高级数据运算和其他类型的操作是更为方便的。 通常情况下,这样的操作比使用Python的内置序列更有效,执行代码更少。 (4)越来越多的用于数学和科学计算Python库使用了Numpy,虽然这些第三方库也留了Python内置序列的输入接口,但是实际上在处理这些输入前还是要转成Numpy数组,平切这些库的输出一般是Numpy数组。换句话说,为了更好的使用当今大多数(甚至是绝大多数)用于数学/科学的Python库,仅仅知道Python本身是远远不够的。

在科学计算中序列的大小和速度是尤其重要的点。举个简单的例子:如果要将一个一维的序列a中的每一个数与另一个序列b(长度与a相同)。数据存放在python的list结构中,通过遍历列表可以得到:

c = []
for i in range(len(a)):
    c.append(a[i]*b[i])

比如 a = [1,2,3],b = [1,1,1],那么 c = [1,2,3] 这样就能求出结果,但是如果a和b中包含了数百万个数,那么循环遍历的代价就会很高。好在我们有更高效的方法(为了更加清晰,我们忽略了变量的声明,初始化和内存分配的代码),比如用C/C++:

for (i = 0; i < rows; i++): {
  c[i] = a[i]*b[i];
}

这种方式照比第一个代码,有效节约了所有涉及解释Python代码(append等等)和操作Python对象(len(a))所带来的开销,但是Python编程简单带来的好处就没有了(因为用了C~~)。此外,随着数组维数的增加,C代码遍历的消耗也会变大,比如在二维数组的情况下,代码要变为:

for (i = 0; i < rows; i++): {
  for (j = 0; j < columns; j++): {
    c[i][j] = a[i][j]*b[i][j];
  }
}

Numpy提供给我们的方式包含了二者的优势(Python的简单和C的效率),逐个元素操作只需要ndarray对象提供的“默认模式”,但是逐个元素的操作可以通过预编译的C代码快速执行。 在NumPy中:

c = a * b

在这个例子中,它的速度和C代码接近,但是做到了像Python代码一样灰常简单的风格!事实上,Numpy的语法还要 更简单一些!上面的例子阐述NumPy中两个最基础也是最重要的功能:vectorization 和 broadcasting。

vectorization :代码中没有任何明确的循环,索引等 - 这些事情当然是在C编写的源码中完成的。 矢量化代码有很多优点,其中包括: (1)简洁易读 (2)代码的行数更少(完成同样功能),这意味着更少的bug (3)代码更像标准的数学符号 (4)比Python的代码更简单一些,避免了循环。

Broadcasting:是用于描述操作的隐含逐个元素行为的术语; 一般来说,在NumPy的所有操作中,不仅仅是算术运算,还有逻辑运算,位操作,功能性的运算,这些算法在表现形式上都隐藏了逐个元素操作的方式,即broadcast。 此外,在上述示例中,a和b可以是相同形状(shape)的多维数组,或标量和序列,或者甚至是具有不同形状的两个数组,只要较小的数组“可扩展”到较大的形状(shape) 以这样一种方式使得最终的broadcast是明确的。 有关broadcast的详细介绍,请参阅numpy.doc.broadcasting

NumPy完全支持面向对象的编程,再次说道ndarray。例如,ndarray是一个类,拥有众多的方法和属性。 它的许多方法在最外层的NumPy命名空间中镜像函数,使程序员能够完全自由地编写任何偏好的范例和最适合手头任务的代码。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习养成记

【实用派】R语言中的便捷小操作

管道处理 管道处理避免了中间变量的生成,从而节省了内存,并且使代码直观易读,很大程度的简化代码。 R语言中,管道运算符为“dplyr”包中的“%>%”,指左边的...

2737
来自专栏刘望舒

Android解析WindowManagerService(二)WMS的重要成员和Window的添加过程

前言 在本系列的上一篇文章中,我们学习了WMS的诞生,WMS被创建后,它的重要的成员有哪些?Window添加过程的WMS部分做了什么呢?这篇文章会给你解答。 1...

1949
来自专栏开源优测

JMeter定时器06

前言 在默认情况下,jmeter发送每个请求之间是没有延时的,如果采用默认方式,如果线程数足够大,瞬间就会将服务器压死。再则在实际的业务过程中,请求之间是有一定...

3286
来自专栏我是攻城师

使用Scala的强大api快速加工数据

3284
来自专栏生信技能树

R for Data Science(十二)

一直觉得编程能力好的人都会写函数,我对R语言写函数能力比较差,就学了这一章节,拆分如何写函数以及为什么写函数 例如我们看一下这个代码

842
来自专栏数值分析与有限元编程

fortran知识 | 代码错误(domain error)

如图所示,提示为:domain error ? 这表示数学函数错误,如超出数学函数的定义域,负数开平方,分母为0等等;也有可能是浮点数错误,比如sqrt(4),...

3466
来自专栏前端架构

js学习思维导图

     能够认真看完就是一次对javascript的回顾与提升,可以很好的检验基础。

411
来自专栏机器学习从入门到成神

java之Vector使用(与ArrayList区分)

ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.util.*;

401
来自专栏逍遥剑客的游戏开发

Bullet的最小化功能封装

1253
来自专栏ATYUN订阅号

帮助数据科学家理解数据的23个pandas常用代码

返回给定轴缺失的标签对象,并在那里删除所有缺失数据(’any’:如果存在任何NA值,则删除该行或列。)。

614

扫码关注云+社区