一: 简单介绍
numpy 的主要对象是同类型的多维数组。它通常是以表格的形式存在,表格里面的元素具有相同的类型,可以通过含正整数的元组索引到相应的元素。在NumPy中,维度被叫做轴
例如,一个3维的点的坐标为:[1,2,3], 它就有一个轴。 这个轴里有三个元素存在,即它的长度为3.
下面是一个轴而2的数组,其中第一个轴的长度为2, 第二个轴的长度为3[[1,2,3],
[3,4,5]]
Numpy的数组类被叫做 ndarray, 当然,它还有另一个别名 array 。注意:numpy.array 不同于 python 标准库里的 array.array. 后者只能处理一维的数组且提供的函数比较少。
下面介绍 ndarray 几个重要的函数ndarray.ndim
返回数组中轴的数量
ndarray.shape
返回数组的维度。它以正整数的元组形式返回每一个轴的长度。比如对于一个n行m列的矩阵, shape 就为 (n,m).
ndarray.size
返回数组所有元素的数目。它是shape元素的乘积。
ndarray.dtype
返回数组中元素的数据类型
ndarray.itemsize
返回数组中元素的字节数。比如,数组元素的数据类型是 float64, 那么返回的itemsize 为 8(64/8). 因为float64的数组中,每一个元素占64个bit, 转化为字节数: 8 = 64 / 8
ndarray.data
返回数组的真实物理地址。这个一般不用。如果要返回元素,用索引会更加方便。
练习
Selection_024.png
二:数组的创建可以用python的list或tupe来创建数组。数组的元素类型会根据数组的元素来推断
Selection_025.png注意:下面是容易犯错点>>> a = np.array(1,2,3,4) # WRONG>>> a = np.array([1,2,3,4]) # RIGHT创建多维数组>>> b = np.array([(1.5,2,3), (4,5,6)])>>> b
array([[ 1.5, 2. , 3. ],
[ 4. , 5. , 6. ]])创建数组的同时可以指定元素类型
如指定数组元素为复数:>>> c = np.array( [ [1,2], [3,4] ], dtype=complex )>>> c
array([[ 1.+0.j, 2.+0.j],
[ 3.+0.j, 4.+0.j]])有时我们并不知道数组元素的值多少,但是直到数组的shape,这时我们可以用 zeros函数 / ones函数 / empty 函数 来创建数组>>> np.zeros( (3,4) )>>> np.empty( (2,3) ) # uninitialized, output may varyarray([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
[ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])创建数列( arrage函数的第一参数表示数列的起始值,第二个参数是数列的上界,取不到,第三参数表示数列之间的距离)>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])>>> np.arange( 0, 2, 0.3 ) # it accepts float argumentsarray([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])用 linespace函数创建数组
前两个参数表示数列的上下界,上下界都取得到。 第三个参数表示要生成多少个元素。>>> from numpy import pi>>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])>>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points>>> f = np.sin(x)```>>> np.empty( (2,3) ) # uninitialized, output may vary
array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260],
[ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])创建数列( arrage函数的第一参数表示数列的起始值,第二个参数是数列的上界,取不到,第三参数表示数列之间的距离)>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])>>> np.arange( 0, 2, 0.3 ) # it accepts float argumentsarray([ 0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])用 linespace函数创建数组
前两个参数表示数列的上下界,上下界都取得到。 第三个参数表示要生成多少个元素。>>> from numpy import pi>>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])>>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points>>> f = np.sin(x)
三: 基础操作元素按位 加 减 乘 除>>> a = np.array( [20,30,40,50] )>>> b = np.arange( 4 )>>> b
array([0, 1, 2, 3])>>> c = a-b>>> c
array([20, 29, 38, 47])>>> b**2array([0, 1, 4, 9])>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])>>> a<35array([ True, True, False, False])
注意:指数操作符是: **矩阵乘法
用 dot 函数 或 @ 操作符(python>3.5)>>> A = np.array( [[1,1],
... [0,1]] )>>> B = np.array( [[2,0],
... [3,4]] )>>> A * B # elementwise productarray([[2, 0],
[0, 4]])>>> A @ B # matrix productarray([[5, 4],
[3, 4]])>>> A.dot(B) # another matrix productarray([[5, 4],
[3, 4]])当操作有多种数据类型的数组时,数组元素的数据类型为精度最大的类型>>> a = np.ones(3, dtype=np.int32)>>> b = np.linspace(0,pi,3)>>> b.dtype.name'float64'>>> c = a+b>>> c
array([ 1. , 2.57079633, 4.14159265])>>> c.dtype.name'float64'>>> d = np.exp(c*1j)>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
-0.54030231-0.84147098j])>>> d.dtype.name'complex128'sum / min / max 函数>>> b = np.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 columnarray([12, 15, 18, 21])>>>
>>> b.min(axis=1) # min of each rowarray([0, 4, 8])>>>
>>> b.cumsum(axis=1) # cumulative sum along each rowarray([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38]])
四:常用函数
注意这些函数都是按位操作的exp() / sqrt() / add()>>> B = np.arange(3)>>> B
array([0, 1, 2])>>> np.exp(B)
array([ 1. , 2.71828183, 7.3890561 ])>>> np.sqrt(B)
array([ 0. , 1. , 1.41421356])>>> C = np.array([2., -1., 4.])>>> np.add(B, C)
array([ 2., 0., 6.])numpy.all(a, axis=None, out=None, keepdims=)
沿着轴测试数组中所有元素是否为True。 如果存在一个为False,就返回False
注意: NaN / 正无穷 / 负无穷都是True,因为它们都不等于0>>> np.all([[True,False],[True,True]])False>>> np.all([[True,False],[True,True]], axis=0)
array([ True, False])>>> np.all([-1, 4, 5])True>>> np.all([1.0, np.nan])True>>> o=np.array([False])>>> z=np.all([-1, 4, 5], out=o)>>> id(z), id(o), z
(28293632, 28293632, array([ True]))numpy.any(a, axis=None, out=None, keepdims=)
跟all函数类似,不过它是如果有一个元素为True,则返回True>>> np.any([[True, False], [True, True]])True>>>>>> np.any([[True, False], [False, False]], axis=0)
array([ True, False])
>>>>>> np.any([-1, 0, 5])True>>>>>> np.any(np.nan)True>>>>>> o=np.array([False])>>> z=np.any([-1, 4, 5], out=o)>>> z, o
(array([ True]), array([ True]))>>> # Check now that z is a reference to o>>> z is oTrue>>> id(z), id(o) # identity of z and o (191614240, 191614240)numpy.apply_along_axis(func1d, axis, arr, *args, **kwargs)
沿着给定的轴作用函数func1d
返回处理过后的数组>>> def my_func(a):... """Average first and last element of a 1-D array"""... return (a[0] + a[-1]) * 0.5>>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])>>> np.apply_along_axis(my_func, 0, b)
array([ 4., 5., 6.])>>> np.apply_along_axis(my_func, 1, b)
array([ 2., 5., 8.])>>> b = np.array([[8,1,7], [4,3,9], [5,2,6]])>>> np.apply_along_axis(sorted, 1, b)
array([[1, 7, 8],
[3, 4, 9],
[2, 5, 6]])>>> b = np.array([[1,2,3], [4,5,6], [7,8,9]])>>> np.apply_along_axis(np.diag, -1, b)
array([[[1, 0, 0],
[0, 2, 0],
[0, 0, 3]],
[[4, 0, 0],
[0, 5, 0],
[0, 0, 6]],
[[7, 0, 0],
[0, 8, 0],
[0, 0, 9]]])numpy.argmax(a, axis=None, out=None)
返回沿着轴最大值的索引>>> a = np.arange(6).reshape(2,3)>>> a
array([[0, 1, 2],
[3, 4, 5]])>>> np.argmax(a)5>>> np.argmax(a, axis=0)
array([1, 1, 1])>>> np.argmax(a, axis=1)
array([2, 2])>>> ind = np.unravel_index(np.argmax(a, axis=None), a.shape)>>> ind
(1, 2)>>> a[ind]5>>> b = np.arange(6)>>> b[1] = 5>>> b
array([0, 5, 2, 3, 4, 5])>>> np.argmax(b) # Only the first occurrence is returned.1numpy.argmin
跟numpy.argmax函数类似numpy.argmax(a, axis=-1, kind='quicksort', order=None)
返回沿着轴排序后的元素在原来数组的索引位置>>> x = np.array([3, 1, 2])>>> np.argsort(x)
array([1, 2, 0])>>> np.argsort(x, axis=0) # sorts along first axis (down)array([[0, 1],
[1, 0]])>>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape)>>> ind
(array([0, 1, 1, 0]), array([0, 0, 1, 1]))>>> x[ind] # same as np.sort(x, axis=None)array([0, 2, 2, 3])# 带关键词的排序>>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '>> x
array([(1, 0), (0, 1)],
dtype=[('x', '>> np.argsort(x, order=('x','y'))
array([1, 0])>>> np.argsort(x, order=('y','x'))
array([0, 1])沿着指定的轴计算平均值>>> data = range(1,5)>>> data
[1, 2, 3, 4]>>> np.average(data)2.5>>> np.average(range(1,11), weights=range(10,0,-1))4.0>>> data = np.arange(6).reshape((3,2))>>> data
array([[0, 1],
[2, 3],
[4, 5]])>>> np.average(data, axis=1, weights=[1./4, 3./4])
array([ 0.75, 2.75, 4.75])>>> np.average(data, weights=[1./4, 3./4])
Traceback (most recent call last):
...TypeError: Axis must be specified when shapes of a and weights differnumpy.bincount(x, weights=None, minlength=0)
遍历数组x, 创建新的数组y(长度是x中的最大值), 对于x中的每一个元素,执行y[x[i]] += 1 或 y[x[i]] += widht[i]
返回y>>> np.bincount(np.arange(5))
array([1, 1, 1, 1, 1])>>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
array([1, 3, 1, 1, 0, 0, 0, 1])>>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23])>>> np.bincount(x).size == np.amax(x)+1True# 输入的数组必须是整形的>>> np.bincount(np.arange(5, dtype=float))
Traceback (most recent call last):
File "", line 1, in TypeError: array cannot be safely cast to required type>>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights>>> x = np.array([0, 1, 1, 2, 2, 2])>>> np.bincount(x, weights=w)
array([ 0.3, 0.7, 1.1])numpy.ceil
向上取整>>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])>>> np.ceil(a)
array([-1., -1., -0., 1., 2., 2., 2.])numpy.clip(a, a_min, a_max, out=None)
把数组限制在指定的区间内>>> a = np.arange(10)>>> np.clip(a, 1, 8)
array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.clip(a, 3, 6, out=a)
array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])>>> a = np.arange(10)>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.clip(a, [3, 4, 1, 1, 1, 4, 4, 4, 4, 4], 8)
array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])numpy.conj(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) =
返回共轭复数>>> np.conjugate(1+2j)
(1-2j)>>> x = np.eye(2) + 1j * np.eye(2)>>> np.conjugate(x)
array([[ 1.-1.j, 0.-0.j],
[ 0.-0.j, 1.-1.j]])numpy.cumprod(a, axis=None, dtype=None, out=None)
沿着轴把元素一个个相乘,并记录中间结果>>> a = np.array([1,2,3])>>> np.cumprod(a) # intermediate results 1, 1*2... # total product 1*2*3 = 6array([1, 2, 6])>>> a = np.array([[1, 2, 3], [4, 5, 6]])>>> np.cumprod(a, dtype=float) # specify type of outputarray([ 1., 2., 6., 24., 120., 720.])numpy.cumsum(a, axis=None, dtype=None, out=None)
沿着轴把元素一个个相加,并记录中间结果>>> a = np.array([[1,2,3], [4,5,6]])>>> a
array([[1, 2, 3],
[4, 5, 6]])>>> np.cumsum(a)
array([ 1, 3, 6, 10, 15, 21])>>> np.cumsum(a, dtype=float) # specifies type of output value(s)array([ 1., 3., 6., 10., 15., 21.])numpy.diff(a, n=1, axis=-1)
沿着轴对相邻的元素做差, 规则: out[n] = a[n+1] - a[n]>>> x = np.array([1, 2, 4, 7, 0])>>> np.diff(x)
array([ 1, 2, 3, -7])>>> np.diff(x, n=2)
array([ 1, 1, -10])numpy.inner(a,b)
内积
p.inner(a, b) = sum(a[:]*b[:])
p.inner(a, b) = np.tensordot(a, b, axes=(-1,-1))>>> a = np.array([1,2,3])>>> b = np.array([0,1,0])>>> np.inner(a, b)>>> a = np.arange(24).reshape((2,3,4))>>> b = np.arange(4)>>> np.inner(a, b)
array([[ 14, 38, 62],
[ 86, 110, 134]])>>> np.inner(np.eye(2), 7)
array([[ 7., 0.],
[ 0., 7.]])>>> a = np.arange(24).reshape((2,3,4))>>> b = np.arange(4)>>> np.inner(a, b)
array([[ 14, 38, 62],
[ 86, 110, 134]])
五 索引,切片,迭代一维数组情况>>> a = np.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 aarray([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000])>>> for i in a:... print(i**(1/3.))
...
nan1.0nan3.0nan5.06.07.08.09.0多维情况下>>> def f(x,y):
... return 10*x+y
...>>> b = np.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 barray([ 1, 11, 21, 31, 41])>>> b[ : ,1] # equivalent to the previous examplearray([ 1, 11, 21, 31, 41])>>> b[1:3, : ] # each column in the second and third row of barray([[10, 11, 12, 13],
[20, 21, 22, 23]])访问最后一个元素>>> b[-1] # the last row. Equivalent to b[-1,:]array([40, 41, 42, 43])使用 dots(...)
dots(...)表示许多个:
比如说 x 是一个5轴的数组,那么:x[1,2,...] is equivalent to x[1,2,:,:,:],
x[...,3] to x[:,:,:,:,3] and
x[4,...,5,:] to x[4,:,:,5,:]>>> c = np.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]
也可以按元素来访问:>>> for element in b.flat:... print(element)
...012310111213202122233031323340414243
六: shape 草组ravel() / reshape() / T
随机给定一个数组的形状>>> a = np.floor(10*np.random.random((3,4)))>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])>>> a.shape
(3, 4)
对数组形状的操作有好多命令,值得注意的是这些命令不改变原来的数组。但是并没有创建新的数组,即没有分配新的内存空间。>>> a.ravel() # returns the array, flattenedarray([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])>>> a.reshape(6,2) # returns the array with a modified shapearray([[ 2., 8.],
[ 0., 6.],
[ 4., 5.],
[ 1., 1.],
[ 8., 9.],
[ 3., 6.]])>>> a.T # returns the array, transposedarray([[ 2., 4., 8.],
[ 8., 5., 9.],
[ 0., 1., 3.],
[ 6., 1., 6.]])>>> a.T.shape
(4, 3)>>> a.shape
(3, 4)resize()
resize() 函数会改变原来数组的形状>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])>>> a.resize((2,6))>>> a
array([[ 2., 8., 0., 6., 4., 5.],
[ 1., 1., 8., 9., 3., 6.]])
如果一个维度被指定为 -1,那么表示改维度会被自动计算>>> a.reshape(3,-1)array([[ 2., 8., 0., 6.], [ 4., 5., 1., 1.], [ 8., 9., 3., 6.]])
七: 不同数组的堆叠不同数组可以不同的轴堆叠>>> a = np.floor(10*np.random.random((2,2)))>>> a
array([[ 8., 8.],
[ 0., 0.]])>>> b = np.floor(10*np.random.random((2,2)))>>> b
array([[ 1., 8.],
[ 0., 4.]])>>> np.vstack((a,b))
array([[ 8., 8.],
[ 0., 0.],
[ 1., 8.],
[ 0., 4.]])>>> np.hstack((a,b))
array([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])column_stack>>> from numpy import newaxis>>> np.column_stack((a,b)) # with 2D arraysarray([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])>>> a = np.array([4.,2.])>>> b = np.array([3.,8.])>>> np.column_stack((a,b)) # returns a 2D arrayarray([[ 4., 3.],
[ 2., 8.]])>>> np.hstack((a,b)) # the result is differentarray([ 4., 2., 3., 8.])>>> a[:,newaxis] # this allows to have a 2D columns vectorarray([[ 4.],
[ 2.]])>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4., 3.],
[ 2., 8.]])>>> np.hstack((a[:,newaxis],b[:,newaxis])) # the result is the samearray([[ 4., 3.],
[ 2., 8.]])r_ 和 c_>>> np.r_[1:4,0,4]array([1, 2, 3, 0, 4])
作者:winddy_akoky
链接:https://www.jianshu.com/p/358948fbbc6e