什么是NumPy

来源:互联网 发布:淘宝个人主页的访客 编辑:程序博客网 时间:2024/05/06 18:44

(原文链接:http://docs.scipy.org/doc/numpy/user/whatisnumpy.html) 现在翻译有些生硬,随后会持续修改。

NumPy是Python科学计算的基础包。它提供了多维数组对象、基于数组的各种派生对象(例如,masked Array, 矩阵)。除此之外,还提供了各种各样的加快数组操作的例程,包括数学基本计算、逻辑、图形操作、排序、选择、输入输出,离散傅立叶变换、基础线性代数、基础统计操作、随机仿真等等。

NumPy的核心是ndarray对象。一方面,Ndarray对象封装了可以包含相同数据类型的多维数组;另一方面,为获得更好的性能, 在ndarray上的操作都是在编译过的代码上执行的。此外,和Python自身的序列对象相比,两者之间有如下不同:

1.       NumPy数组的大小是固定的。Python的List是可以动态增长的。改变NumPy的大小会重新创建一个新的数组并把原来的删掉。

2.       NumPy数组中的元素一定是同一类型的。(相应地,每个元素所占的内存大小也是一样的。)例外情况是:(不是特别理解:one can have arrays of (Python, including NumPy) objects, thereby allowing for arrays of different sized elements.)

3.       NumPy数组支持在大量数据上进行数学计算和其他类型的操作。通常情况下,与Python自带的序列类型相比,NumPy数组上的操作执行更高效,代码量也更少。

4.       越来越多的Python科学计算包都是用到了NumPy的数组;虽然这些库支持Python序列类型的输入,但是内部操作还是要先将其转换为NumPy的数组类型,而且输出通常就是NumPy数组。所以,如果你想要高效地使用这些Python的科学计算包,仅仅知道Python内建的序列类型是不够的,你还需要知道如何使用NumPy数组。

下面通过一些例子和比较来说明NumPy如此强大的两大基础:vectorization and broadcasting 向量化和广播。 假设我们有两个数组a[n],b[n],我要计算出数组c,使得c[0]=a[0]*a[0], c[1]=a[1]*b[1],…,c[n]=a[n]*b[n]。

Python的相应代码是:

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

Python代码的正确性应该没什么问题。问题是如果数据量很大,这样的Python循环速度会很慢。要想快,还是要用C语言试一下,代码如下:(为了清晰性,代码略去了变量声明初始化和内存分配的代码)

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

C语言实现省去了因为解释Python代码和操作Python对象而引入的消耗。代价是失去了Python的好处:代码简洁等等。

更进一步,代码工作量会随着数组维数的上升而增加。例如,如果要类似地计算2维的数组,C语言的代码就要扩展成如下形式:

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

而NumPy的ndarray就解决了上面的问题,代码简洁,速度优良,代码量不随维数的上升而增加。 在NumPy中,下面一行代码就可以实现上面的功能,而且它的速度和C语言实现差不多。

c = a * b

代码中,a,b的类型都是ndarray,分别用来表示数组a[n]和b[n]。在ndarray上,元素对元素的操作是ndarray的默认行为。而且这种元素对元素操作的执行过程是以编译好的C代码形式执行的。

这里我们就可解释什么是向量化和广播了;

向量化指的是在代码中,不需要显示的循环和索引等等,这些操作是在优化且编译好的C代码里面“背地里”做的。向量化的代码有很多优势,如下:

1.  向量化的代码更加简洁易读

2.  向量化的代码行数少。代码行数越少越以为者bug越少

3.  向量化的代码更接近数学中的表达形式和符号

4.  向量化的代码既Pythoic又高效。

广播这一术语是用来描述隐式的元素对元素的操作行为。一般说来,在所有NumPy操作中,不仅仅是算数运算,还包括逻辑运算、位运算、函数运算等等,都会以隐式的元素对元素的运算风格,也就是说广播(广泛散布的)。进一步讲,在上面的例子中,a和b可以是同形(各维大小一样)的多维数组、标量和一位数组,甚至是两个不同形的数组(因为小的数组可以扩展成和较大数组一样大小的形状,这样的话消除了歧义。)。有关广播的更详细规则,参见:numpy.doc.broadcasting.

 最后,NumPy完全支持面向对象的范式。例如,ndarray是一个类,它拥有许多方法和属性。它的许多方法都映射到了最外层的NumPy命名空间的函数里。这样一来,就可以给程序员更多的自由:程序员可以自由选者是面向对象的方式还是面向过程的方式使用这些接口。

 

0 0