在阅读这个教程之前,你多少需要知道点 python。如果你想从新回忆下,请看看 .
如果你想要运行教程中的示例,你至少需要在你的电脑上安装了以下一些软件:
这些是可能对你有帮助的:
NumPy 的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格 (通常是元素是数字)。在 NumPy 中维度(dimensions) 叫做轴(axes),轴的个数叫做秩(rank)。
例如,在 3D 空间一个点的坐标
是一个秩为 1 的数组,因为它只有一个轴。那个轴长度为 3. 又例如,在以下例子中,数组的秩为 2(它有两个维度). 第一个维度长度为 2, 第二个维度长度为 3.
- [1, 2, 3]
- [[1., 0., 0.], [0., 1., 2.]]
NumPy 的数组类被称作 ndarray 。通常被称作数组。注意 numpy.array 和标准 Python 库类 array.array 并不相同,后者只处理一维数组和提供少量功能。更多重要 ndarray 对象属性有:
- >>> from numpy import * >>>a = arange(15).reshape(3, 5) >>> a array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.shape(3, 5) >>> a.ndim 2 >>> a.dtype.name 'int32' >>> a.itemsize 4 >>> a.size 15 >>> type(a) numpy.ndarray >>> b = array([6, 7, 8]) >>> b array([6, 7, 8]) >>> type(b) numpy.ndarray
有好几种创建数组的方法。
例如,你可以使用
函数从常规的 Python 列表和元组创造数组。所创建的数组类型由原序列中的元素类型推导而来。
- array
- >>> from numpy import * >>>a = array([2, 3, 4]) >>> a array([2, 3, 4]) >>> a.dtype dtype('int32') >>> b = array([1.2, 3.5, 5.1]) >>> b.dtype dtype('float64')一个常见的错误包括用多个数值参数调用`array`而不是提供一个由数值组成的列表作为一个参数。 >>> a = array(1, 2, 3, 4)#WRONG >>> a = array([1, 2, 3, 4])#RIGHT
数组将序列包含序列转化成二维的数组,序列包含序列包含序列转化成三维数组等等。
- >>> b = array([(1.5, 2, 3), (4, 5, 6)]) >>> b array([[1.5, 2., 3.], [4., 5., 6.]])
数组类型可以在创建时显示指定
- >>> c = array([[1, 2], [3, 4]], dtype = complex) >>> c array([[1. + 0.j, 2. + 0.j], [3. + 0.j, 4. + 0.j]])
通常,数组的元素开始都是未知的,但是它的大小已知。因此,NumPy 提供了一些使用占位符创建数组的函数。这最小化了扩展数组的需要和高昂的运算代价。
函数 zeros 创建一个全是 0 的数组,函数
创建一个全 1 的数组,函数
- ones
创建一个内容随机并且依赖与内存状态的数组。默认创建的数组类型 (dtype) 都是 float64。
- empty
- >>> zeros((3, 4)) array([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]) >>> ones((2, 3, 4), dtype = int16)#dtype can also be specified 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]]], dtype = int16) >>> empty((2, 3)) array([[3.73603959e-262, 6.02658058e-154, 6.55490914e-260], [5.30498948e-313, 3.14673309e-307, 1.00000000e + 000]])
为了创建一个数列,NumPy 提供一个类似 arange 的函数返回数组而不是列表:
- >>> arange(10, 30, 5) array([10, 15, 20, 25]) >>> arange(0, 2, 0.3)#it accepts float arguments array([0., 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])
当
使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素个数。因此,最好使用函数
- arange
去接收我们想要的元素个数来代替用 range 来指定步长。
- linspace
其它函数 array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, rand, randn, fromfunction, fromfile 参考:
当你打印一个数组,NumPy 以类似嵌套列表的形式显示它,但是呈以下布局:
一维数组被打印成行,二维数组成矩阵,三维数组成矩阵列表。
- >>> a = arange(6)#1d array >>> print a[0 1 2 3 4 5] >>> >>>b = arange(12).reshape(4, 3)#2d array >>> print b[[0 1 2][3 4 5][6 7 8][9 10 11]] >>> >>>c = arange(24).reshape(2, 3, 4)#3d array >>> print c[[[0 1 2 3][4 5 6 7][8 9 10 11]][[12 13 14 15][16 17 18 19][20 21 22 23]]]
查看形状操作一节获得有关 reshape 的更多细节
如果一个数组用来打印太大了,NumPy 自动省略中间部分而只打印角落
- >>> print arange(10000)[0 1 2..., 9997 9998 9999] >>> >>>print arange(10000).reshape(100, 100)[[0 1 2..., 97 98 99][100 101 102..., 197 198 199][200 201 202..., 297 298 299]..., [9700 9701 9702..., 9797 9798 9799][9800 9801 9802..., 9897 9898 9899][9900 9901 9902..., 9997 9998 9999]]
禁用 NumPy 的这种行为并强制打印整个数组,你可以设置 printoptions 参数来更改打印选项。
- >>> set_printoptions(threshold = 'nan')
数组的算术运算是按元素的。新的数组被创建并且被结果填充。
- >>> a = array([20, 30, 40, 50]) >>> b = arange(4) >>> b array([0, 1, 2, 3]) >>> c = a - b >>> c array([20, 29, 38, 47]) >>> b * *2 array([0, 1, 4, 9]) >>> 10 * sin(a) array([9.12945251, -9.88031624, 7.4511316, -2.62374854]) >>> a < 35 array([True, True, False, False], dtype = bool)
不像许多矩阵语言,NumPy 中的乘法运算符
指示按元素计算,矩阵乘法可以使用
- *
函数或创建矩阵对象实现 (参见教程中的矩阵章节)
- dot
- >>> A = array([[1, 1], ... [0, 1]]) >>> B = array([[2, 0], ... [3, 4]]) >>> A * B#elementwise product array([[2, 0], [0, 4]]) >>> dot(A, B)#matrix product array([[5, 4], [3, 4]])
有些操作符像
和
- +=
被用来更改已存在数组而不创建一个新的数组。
- *=
- >>> a = ones((2, 3), dtype = int) >>> b = random.random((2, 3)) >>> a *= 3 >>> a array([[3, 3, 3], [3, 3, 3]]) >>> b += a >>> b array([[3.69092703, 3.8324276, 3.0114541], [3.18679111, 3.3039349, 3.37600289]]) >>> a += b#b is converted to integer type >>> a array([[6, 6, 6], [6, 6, 6]])
当运算的是不同类型的数组时,结果数组和更普遍和精确的已知 (这种行为叫做 upcast)。
- >>> a = ones(3, dtype = int32) >>> b = linspace(0, pi, 3) >>> b.dtype.name 'float64' >>> c = a + b >>> c array([1., 2.57079633, 4.14159265]) >>> c.dtype.name 'float64' >>> d = exp(c * 1j) >>> d array([0.54030231 + 0.84147098j, -0.84147098 + 0.54030231j, -0.54030231 - 0.84147098j]) >>> d.dtype.name 'complex128'许多非数组运算,如计算数组所有元素之和,被作为ndarray类的方法实现 >>> a = random.random((2, 3)) >>> a array([[0.6903007, 0.39168346, 0.16524769], [0.48819875, 0.77188505, 0.94792155]]) >>> a.sum() 3.4552372100521485 >>> a.min() 0.16524768654743593 >>> a.max() 0.9479215542670073
这些运算默认应用到数组好像它就是一个数字组成的列表,无关数组的形状。然而,指定
参数你可以吧运算应用到数组指定的轴上:
- axis
- >>> b = arange(12).reshape(3, 4) >>> b array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]) >>> >>>b.sum(axis = 0)#sum of each column array([12, 15, 18, 21]) >>> >>>b.min(axis = 1)#min of each row array([0, 4, 8]) >>> >>>b.cumsum(axis = 1)#cumulative sum along each row array([[0, 1, 3, 6], [4, 9, 15, 22], [8, 17, 27, 38]])
NumPy 提供常见的数学函数如
,
- sin
和
- cos
。在 NumPy 中,这些叫作 "通用函数"(ufunc)。在 NumPy 里这些函数作用按数组的元素运算,产生一个数组作为输出。
- exp
- >>> B = arange(3) >>> B array([0, 1, 2]) >>> exp(B) array([1., 2.71828183, 7.3890561]) >>> sqrt(B) array([0., 1., 1.41421356]) >>> C = array([2., -1., 4.]) >>> add(B, C) array([2., 0., 6.])
更多函数 all, alltrue, any, apply along axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, conjugate, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sometrue, sort, std, sum, trace, transpose, var, vdot, vectorize, where 参见:
一维 数组可以被索引、切片和迭代,就像 和其它 Python 序列。
- >>> a = arange(10) * *3 >>> a array([0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) >>> a[2] 8 >>> a[2 : 5] array([8, 27, 64]) >>> a[: 6 : 2] = -1000#equivalent to a[0 : 6 : 2] = -1000;
- from start to position 6,
- exclusive,
- set every 2nd element to - 1000 >>> a array([ - 1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729]) >>> a[: :-1]#reversed a array([729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000]) >>>
- for i in a: ...print i * *(1 / 3.),
- ...nan 1.0 nan 3.0 nan 5.0 6.0 7.0 8.0 9.0
多维 数组可以每个轴有一个索引。这些索引由一个逗号分割的元组给出。
- >>> def f(x, y) : ...
- return 10 * x + y... >>> b = fromfunction(f, (5, 4), dtype = int) >>> b array([[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33], [40, 41, 42, 43]]) >>> b[2, 3] 23 >>> b[0 : 5, 1]#each row in the second column of b array([1, 11, 21, 31, 41]) >>> b[: , 1]#equivalent to the previous example array([1, 11, 21, 31, 41]) >>> b[1 : 3, :]#each column in the second and third row of b array([[10, 11, 12, 13], [20, 21, 22, 23]])
当少于轴数的索引被提供时,确失的索引被认为是整个切片:
- >>> b[ - 1]#the last row.Equivalent to b[ - 1, :] array([40, 41, 42, 43])
中括号中的表达式被当作
- b[i]
和一系列
- i
,来代表剩下的轴。NumPy 也允许你使用 "点" 像
- :
。
- b[i,...]
点 (…) 代表许多产生一个完整的索引元组必要的分号。如果 x 是秩为 5 的数组 (即它有 5 个轴),那么:
- >>> c = array([[[0, 1, 2], #a 3D array(two stacked 2D arrays)... [10, 12, 13]], ...... [[100, 101, 102], ... [110, 112, 113]]]) >>> c.shape(2, 2, 3) >>> c[1, ...]#same as c[1, :, :] or c[1] array([[100, 101, 102], [110, 112, 113]]) >>> c[..., 2]#same as c[: , :, 2] array([[2, 13], [102, 113]])
迭代 多维数组是就第一个轴而言的:
- >>>
- for row in b: ...print row... [0 1 2 3][10 11 12 13][20 21 22 23][30 31 32 33][40 41 42 43]
然而,如果一个人想对每个数组中元素进行运算,我们可以使用 flat 属性,该属性是数组元素的一个迭代器:
- >>>
- for element in b.flat: ...print element,
- ...0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43
更多 [], …, newaxis, ndenumerate, indices, index exp 参考
一个数组的形状由它每个轴上的元素个数给出:
- >>> a = floor(10 * random.random((3, 4))) >>> a array([[7., 5., 9., 3.], [7., 2., 7., 8.], [6., 8., 3., 2.]]) >>> a.shape(3, 4)
一个数组的形状可以被多种命令修改:
- >>> a.ravel()#flatten the array array([7., 5., 9., 3., 7., 2., 7., 8., 6., 8., 3., 2.]) >>> a.shape = (6, 2) >>> a.transpose() array([[7., 9., 7., 7., 6., 3.], [5., 3., 2., 8., 8., 2.]])
由
展平的数组元素的顺序通常是 "C 风格" 的,就是说,最右边的索引变化得最快,所以元素 a[0,0]之后是 a[0,1]。如果数组被改变形状 (reshape) 成其它形状,数组仍然是 "C 风格" 的。NumPy 通常创建一个以这个顺序保存数据的数组,所以
- ravel()
将总是不需要复制它的参数 。但是如果数组是通过切片其它数组或有不同寻常的选项时,它可能需要被复制。函数
- ravel()
和
- reshape()
还可以被同过一些可选参数构建成 FORTRAN 风格的数组,即最左边的索引变化最快。
- ravel()
函数改变参数形状并返回它,而
- reshape
函数改变数组自身。
- resize
- >>> a array([[7., 5.], [9., 3.], [7., 2.], [7., 8.], [6., 8.], [3., 2.]]) >>> a.resize((2, 6)) >>> a array([[7., 5., 9., 3., 7., 2.], [7., 8., 6., 8., 3., 2.]])
如果在改变形状操作中一个维度被给做 - 1,其维度将自动被计算
更多 shape, reshape, resize, ravel 参考
几种方法可以沿不同轴将数组堆叠在一起:
- >>> a = floor(10 * random.random((2, 2))) >>> a array([[1., 1.], [5., 8.]]) >>> b = floor(10 * random.random((2, 2))) >>> b array([[3., 3.], [6., 0.]]) >>> vstack((a, b)) array([[1., 1.], [5., 8.], [3., 3.], [6., 0.]]) >>> hstack((a, b)) array([[1., 1., 3., 3.], [5., 8., 6., 0.]])
函数
以列将一维数组合成二维数组,它等同与
- column_stack
对一维数组。
- vstack
- >>> column_stack((a, b))#With 2D arrays array([[1., 1., 3., 3.], [5., 8., 6., 0.]]) >>> a = array([4., 2.]) >>> b = array([2., 8.]) >>> a[: , newaxis]#This allows to have a 2D columns vector array([[4.], [2.]]) >>> column_stack((a[: , newaxis], b[: , newaxis])) array([[4., 2.], [2., 8.]]) >>> vstack((a[: , newaxis], b[: , newaxis]))#The behavior of vstack is different array([[4.], [2.], [2.], [8.]])
函数,另一方面,将一维数组以行组合成二维数组。
- row_stack
对那些维度比二维更高的数组,
沿着第二个轴组合,
- hstack
沿着第一个轴组合,
- vstack
允许可选参数给出组合时沿着的轴。
- concatenate
Note
在复杂情况下,
和
- r_[]
对创建沿着一个方向组合的数很有用,它们允许范围符号 (":"):
- c_[]
- >>> r_[1 : 4, 0, 4] array([1, 2, 3, 0, 4])
当使用数组作为参数时,
和
- r_
的默认行为和
- c_
和
- vstack
很像,但是允许可选的参数给出组合所沿着的轴的代号。
- hstack
更多函数 hstack , vstack, column_stack , row_stack , concatenate , c_ , r_ 参见 .
使用
你能将数组沿着它的水平轴分割,或者指定返回相同形状数组的个数,或者指定在哪些列后发生分割:
- hsplit
- >>> a = floor(10 * random.random((2, 12))) >>> a array([[8., 8., 3., 9., 0., 4., 3., 0., 0., 6., 4., 4.], [0., 3., 2., 9., 6., 0., 4., 5., 7., 5., 1., 4.]]) >>> hsplit(a, 3)#Split a into 3[array([[8., 8., 3., 9.], [0., 3., 2., 9.]]), array([[0., 4., 3., 0.], [6., 0., 4., 5.]]), array([[0., 6., 4., 4.], [7., 5., 1., 4.]])] >>> hsplit(a, (3, 4))#Split a after the third and the fourth column[array([[8., 8., 3.], [0., 3., 2.]]), array([[9.], [9.]]), array([[0., 4., 3., 0., 0., 6., 4., 4.], [6., 0., 4., 5., 7., 5., 1., 4.]])]
沿着纵向的轴分割,
- vsplit
允许指定沿哪个轴分割。
- array
- split
当运算和处理数组时,它们的数据有时被拷贝到新的数组有时不是。这通常是新手的困惑之源。这有三种情况:
简单的赋值不拷贝数组对象或它们的数据。
- >>> a = arange(12) >>> b = a#no new object is created >>> b is a#a and b are two names
- for the same ndarray object True >>> b.shape = 3,
- 4#changes the shape of a >>> a.shape(3, 4)
Python 传递不定对象作为参考 ,所以函数调用不拷贝数组。
- >>> def f(x) : ...print id(x)... >>> id(a)#id is a unique identifier of an object 148293216 >>> f(a) 148293216
不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据。
- >>> c = a.view() >>> c is a False >>> c.base is a#c is a view of the data owned by a True >>> c.flags.owndata False >>> >>>c.shape = 2,
- 6#a 's shape doesn't change >>> a.shape(3, 4) >>> c[0, 4] = 1234#a 's data changes
- >>> a
- array([[ 0, 1, 2, 3],
- [1234, 5, 6, 7],
- [ 8, 9, 10, 11]])'
切片数组返回它的一个视图:
- >>> s = a[: , 1 : 3]#spaces added
- for clarity;
- could also be written "s = a[:,1:3]" >>> s[: ] = 10#s[: ] is a view of s.Note the difference between s = 10 and s[: ] = 10 >>> a array([[0, 10, 10, 3], [1234, 10, 10, 7], [8, 10, 10, 11]])
这个复制方法完全复制数组和它的数据。
- >>> d = a.copy()#a new array object with new data is created >>> d is a False >>> d.base is a#d doesn 't share anything with a
- False
- >>> d[0,0] = 9999
- >>> a
- array([[ 0, 10, 10, 3],
- [1234, 10, 10, 7],
- [ 8, 10, 10, 11]])'
这是个 NumPy 函数和方法分类排列目录。这些名字链接到 , 你可以看到这些函数起作用。[^5]
创建数组
- arange,
- array,
- copy,
- empty,
- empty_like,
- eye,
- fromfile,
- fromfunction,
- identity,
- linspace,
- logspace,
- mgrid,
- ogrid,
- ones,
- ones_like,
- r,
- zeros,
- zeros_like
转化
- astype,
- atleast 1d,
- atleast 2d,
- atleast 3d,
- mat
操作
- array split,
- column stack,
- concatenate,
- diagonal,
- dsplit,
- dstack,
- hsplit,
- hstack,
- item,
- newaxis,
- ravel,
- repeat,
- reshape,
- resize,
- squeeze,
- swapaxes,
- take,
- transpose,
- vsplit,
- vstack
询问
- all,
- any,
- nonzero,
- where
排序
- argmax,
- argmin,
- argsort,
- max,
- min,
- ptp,
- searchsorted,
- sort
运算
- choose,
- compress,
- cumprod,
- cumsum,
- inner,
- fill,
- imag,
- prod,
- put,
- putmask,
- real,
- sum
基本统计
- cov,
- mean,
- std,
- var
基本线性代数
- cross,
- dot,
- outer,
- svd,
- vdot
来源: http://lib.csdn.net/article/python/47309