属性简介
NumPy的主要对象是齐次多维数组。它是由非负整数元组索引的所有类型相同的元素(通常为数字)表。NumPy的数组类称为ndarray。别名数组也知道它。请注意,numpy.array与标准Python库类array.array不同,后者仅处理一维数组且功能较少。
- ndarray.ndim:数组的轴数(尺寸) 轴数阵列的(尺寸)
- ndarray.shape:数组的尺寸
- ndarray.size:数组元素的总数
- ndarray.dtype:数据类型,可以用python类创建,也可以用np创建如:numpy.int32
- ndarray.itemsize:数组中元素大小,指定的格式为:ndarray.dtype.itemsize
- ndarray.data:包含数组实际元素的缓冲区(通常不会用到)
import numpy as np
a = np.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
#结果:'int64'
a.itemsize
#结果:8
a.size
#结果:15
type(a)
#结果:<class 'numpy.ndarray'>
b = np.array([6, 7, 8])
b
#结果:array([6, 7, 8])
type(b)
#结果:<class 'numpy.ndarray'>
ndarray的创建
这部分没有什么好说的直接上代码:
a = np.array([2,3,4])#创建整形数据
b = np.array([1.2, 3.5, 5.1])#创建浮点型数据
b = np.array([(1.5,2,3), (4,5,6)])#创建浮点型
c = np.array( [ [1,2], [3,4] ], dtype=complex )#指定复数类型
b = np.array([(1.5,2,3), (4,5,6)])#np会将序列看做数组类型读入
#创建具有站位性质的ndarry(默认float64类型)
np.zeros( (3,4) )
#结果
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
#当然可以指定数据类型
np.ones( (2,3,4), dtype=np.int16 )
np.empty( (2,3) )
np.arange( 10, 30, 5 )#与range用法结合
np.linspace( 0, 2, 9 )#防止因为浮点数据被pass掉
x = np.linspace( 0, 2*pi, 100 )
f = np.sin(x)
#创建随机数
b = rg.random((2,3))
np中进行初始化创建还有以下命令:
- np.zeros_like(没啥说的,字面意思,创建形状相同的矩阵)
- np.ones_like
- np.empty_like
- numpy.random.Generator.rand,
- numpy.random.Generator.randn,
- np.fromfunction:fromfunction(function,shape,dtype )
- np.fromfile:a.tofile()和np.fromfile()需要配合使用 可以通过元数据文件来存储额外信息
- np.loadtxt:加载TXT文件,输入地址即可
np中创建初始矩阵的命令很多,在这里就不一一赘述了,对此方面要求更高的,参考这位老哥的文章
强制打印
如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,仅打印角点,如果需要打印全部数据,需要加入
np.set_printoptions(threshold=sys.maxsize)
基本运算
运算符合向上转换规则
对应元素相乘
其支持的运算类型很多:
- 加减:c = a-b
- 乘除,乘方:d=b**2
- 函数:10*np.sin(a)
- 布尔运算:a<35
矩阵相乘
矩阵相乘通过@符号或者点函数实现
A @ B
A.dot(B)
拼接运算一样可以使用
a *= 3
b += a
内置函数运算
b.sum(axis=0)
b.min(axis=1)
b.cumsum(axis=1)#累加,axis是指定运算的轴,一般为一时进行行运算
np.exp(B)#自然指数
np.sqrt(B)#开放
np.add(B, C)
A.dot(B)#矩阵乘法
切片和迭代
切片
- a[2:5]:取序列号2到5,包含2但不包含5
- a[:6:2]:0到6,步长为2
- a[ : :-1]:倒序排列
- b[0:5, 1]:第二列的前5行的数
- b[ : ,1]:第二列的全部数
- b[-1] :最后一行
- x[1,2,…] 等价于 x[1,2,:,:,:]:复杂数组对轴进行操作
举例:仅对最后一例
>>> 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]])
hsplit(),指按照横轴方向,对数组进行分割操作,vsplit是按照纵轴进行分割
>>> a = np.floor(10*rg.random((2,12)))
>>> a
array([[6., 7., 6., 9., 0., 5., 4., 0., 6., 8., 5., 2.],
[8., 5., 5., 7., 1., 8., 6., 7., 1., 8., 1., 0.]])
# Split a into 3
>>> np.hsplit(a,3)
[array([[6., 7., 6., 9.],
[8., 5., 5., 7.]]), array([[0., 5., 4., 0.],
[1., 8., 6., 7.]]), array([[6., 8., 5., 2.],
[1., 8., 1., 0.]])]
# Split a after the third and the fourth column
>>> np.hsplit(a,(3,4))
[array([[6., 7., 6.],
[8., 5., 5.]]), array([[9.],
[7.]]), array([[0., 5., 4., 0., 6., 8., 5., 2.],
[1., 8., 6., 7., 1., 8., 1., 0.]])]
迭代
第一主轴迭代
for row in b:
元素迭代
**for element in b.flat:**用flat属性
形状操作
>>> a = np.floor(10*rg.random((3,4)))#向下取整
>>> a
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
>>> a.shape
(3, 4)
>>> a.ravel() # 数组展平且顺序通常是“ C样式”,即最右边的索引“更改最快
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])
>>> a.reshape(6,2)
array([[3., 7.],
[3., 4.],
[1., 4.],
[2., 2.],
[7., 2.],
[4., 9.]])
>>> a.T # 矩阵转置
array([[3., 1., 7.],
[7., 4., 2.],
[3., 2., 4.],
[4., 2., 9.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)
#reshape函数以修改后的形状返回其参数,而ndarray.resize方法修改数组本身
>>> a
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
>>> a.resize((2,6))
>>> a
array([[3., 7., 3., 4., 1., 4.],
[2., 2., 7., 2., 4., 9.]])
>>> a.reshape(3,-1)#如果标注为-1,则该参数自动计算。其他改变形状的命令也同样适用
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
数组的复制问题
未复制
>>> a = np.arange(12)
>>> b = a
>>> b is a # a 和 b 是一个 ndarray 对象的两个名称
True
>>> b.shape = 3,4
>>> a.shape
(3, 4)
浅复制
享有共同的数据,但含有不同的形状
>>> c = a.view()
>>> c is a
False
>>> c.base is a
True
>>> c.flags.owndata
False
>>>
>>> c.shape = 2,6
>>> a.shape
(3, 4)
>>> c[0,4] = 1234
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
完全复制
d和a不共享任何东西
>>> d = a.copy()
>>> d is a
False
>>> d.base is a
False
>>> d[0,0] = 9999
>>> a
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
[ 8, 10, 10, 11]])
函数与方法
创建数组的函数部分已经介绍过一部分常用的了,这里在这方面不在赘述
1.ndarray.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
拷贝并进行强制类型转换
x = np.array([1, 2, 2.5])
x.astype(int)
#结果:array([1, 2, 2])
2.numpy.atleast_1d(*arys)
跟2d,3d一样,其具有过滤作用,过滤掉低维的矩阵
3.numpy.mat(data, dtype=None)
将输入数据转化为矩阵
4.numpy.array_split(ary, indices_or_sections, axis=0)
切片
x = np.arange(8.0)
np.array_split(x, 3)
#结果:[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7.])]
5.numpy.column_stack(tup)
数组堆叠
a = np.array((1,2,3))
b = np.array((2,3,4))
np.column_stack((a,b))
#结果:array([[1, 2],
# [2, 3],
# [3, 4]])
同理: hstack, vstack分别对应行堆叠,列堆叠。
6.numpy.diagonal(a, offset=0, axis1=0, axis2=1)
返回对角线
7.numpy.dsplit(ary, indices_or_sections)
按深度进行切片
8.ndarray.item(*args)
返回标准的python标量
array([[2, 2, 6],
[1, 3, 6],
[1, 0, 1]])
x.item(3)
out:1
x.item(7)
out:0
9.numpy.repeat(a, repeats, axis=None)
字面意思
np.repeat(3, 4)
out:array([3, 3, 3, 3])
10.numpy.squeeze(a, axis=None)
从数组形状中删除一维条目, 从阵列的形状除去单维输入。
x = np.array([[[0], [1], [2]]])
x.shape
out:(1, 3, 1)
np.squeeze(x).shape
out:(3,)
11.numpy.swapaxes(a, axis1, axis2)
字面意思互换轴
12.numpy.take(a, indices, axis=None, out=None, mode='raise')
a = [4, 3, 5, 7, 6, 8]
indices = [0, 1, 4]
np.take(a, indices)
#out:array([4, 3, 6])
np.take(a, [[0, 1], [2, 3]])
13.numpy.transpose(a, axes=None)
将轴反转,如果是二维的则相当于矩阵转置
14.numpy.all(a, axis=None, out=None, keepdims=<no value>)
测试沿给定轴的所有数组元素是否求值为True
15.numpy.any(a, axis=None, out=None, keepdims=<no value>)[source]
测试沿给定轴的所有元素是否求值为True
16.numpy.nonzero(a)
返回非零元素的索引(可与布尔运算结合)
17.numpy.where(condition[, x, y])
上代码自己体会
a = np.arange(10)
#out:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.where(a < 5, a, 10*a)
#out:array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])
18.numpy.argmax(a, axis=None, out=None)
沿轴返回最大值的索引值,同理argmin
19.numpy.argsort(a, axis=-1, kind=None, order=None)
返回排序的索引
x = np.array([3, 1, 2])
np.argsort(x)
#out:array([1, 2, 0])
20.numpy.ptp
返回沿轴线最大最小值的范围
x = np.arange(4).reshape((2,2))
#array([[0, 1],
# [2, 3]])
np.ptp(x, axis=0)
#array([2, 2])
np.ptp(x, axis=1)
#array([1, 1])
21.numpy.searchsorted
查找应在其中插入元素以保持顺序的索引
np.searchsorted([1,2,3,4,5], 3)
#out:2
22.numpy.sort
返回数组的排序副本
23.numpy.choose(a, choices, out=None, mode='raise')
函数并不是很简单,把参数说明列一下(每组取索引号的值):
choices = [[0, 1, 2, 3], [10, 11, 12, 13],
[20, 21, 22, 23], [30, 31, 32, 33]]
np.choose([2, 3, 1, 0], choices)
#out:array([20, 31, 12, 3])
23.numpy.compress(condition, a, axis=None, out=None)
指定的行或者列进行切片
a = np.array([[1, 2], [3, 4], [5, 6]])
a = np.array([[1, 2], [3, 4], [5, 6]])
#out:array([[3, 4],
# [5, 6]])
24.numpy.cumprod
跟之前的累加一样,这个函数的效果是累乘
a = np.array([1,2,3])
np.cumprod(a)
#out:array([1, 2, 6])
25.numpy.inner(a, b)
数组内积
26.ndarray.fill(value)
用标量值填充数组
a = np.array([1, 2])
a.fill(0)
#array([0, 0])
27.numpy.imag(val)
返回复数的虚部
28.numpy.prod(a, axis=None, dtype=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
返回累乘结果
29.numpy.put(a, ind, v, mode='raise')
替换指定序列元素
a = np.arange(5)
np.put(a, [0, 2], [-44, -55])
#array([-44, 1, -55, 3, 4])
30.numpy.putmask(a, mask, values)
与where类似
x = np.arange(6).reshape(2, 3)
np.putmask(x, x>2, x**2)
#array([[ 0, 1, 2],
# [ 9, 16, 25]])
31.numpy.real(val)
返回复数实部
32.numpy.cov
给定数据和权重,估计协方差矩阵
33.numpy.mean(a, axis=None, dtype=None, out=None, keepdims=<no value>)
沿指定轴计算算术平均值
a = np.array([[1, 2], [3, 4]])
np.mean(a)
#out:2.5
34.numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>)
计算标准差
35.numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<no value>)
计算方差
36.numpy.cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None)
返回向量交叉积
37.numpy.outer(a, b, out=None)
返回外积
38.numpy.linalg.svd(a, full_matrices=True, compute_uv=True, hermitian=False)
奇异值分解
39.numpy.vdot(a, b)
返回向量点乘积能计算复数乘积
总述
**上面很多函数只是简单介绍了其基本实现的功能,而且不够全面,有很多函数没能叙述,只是罗列了一些最基本的内容,以期能够实现一个numpy上的简单入门,而不是精通,如果有啥叙述不清楚的,请直接查看官网
更高级一点的索引技巧
这里边的所含内容,直接用官方代码展示吧:
>>> a = np.arange(12)**2 # the first 12 square numbers
>>> i = np.array( [ 1,1,3,8,5 ] ) # an array of indices
>>> a[i] # the elements of a at the positions i
array([ 1, 1, 9, 64, 25])
>>>
>>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # a bidimensional array of indices
>>> a[j] # the same shape as j
array([[ 9, 16],
[81, 49]])
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> i = np.array( [ [0,1], # indices for the first dim of a
... [1,2] ] )
>>> j = np.array( [ [2,1], # indices for the second dim
... [3,3] ] )
>>>
>>> a[i,j] # i and j must have equal shape
array([[ 2, 5],
[ 7, 11]])
>>>
>>> a[i,2]
array([[ 2, 6],
[ 6, 10]])
>>>
>>> a[:,j] # i.e., a[ : , j]
array([[[ 2, 1],
[ 3, 3]],
[[ 6, 5],
[ 7, 7]],
[[10, 9],
[11, 11]]])
使用数组建立索引的另一种常见用法是搜索时间相关序列的最大值:
>>> time = np.linspace(20, 145, 5) # time scale
>>> data = np.sin(np.arange(20)).reshape(5,4) # 4 time-dependent series
>>> time
array([ 20. , 51.25, 82.5 , 113.75, 145. ])
>>> data
array([[ 0. , 0.84147098, 0.90929743, 0.14112001],
[-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ],
[ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
[-0.53657292, 0.42016704, 0.99060736, 0.65028784],
[-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
# index of the maxima for each series
>>> ind = data.argmax(axis=0)
>>> ind
array([2, 0, 3, 1])
# times corresponding to the maxima
>>> time_max = time[ind]
>>>
>>> data_max = data[ind, range(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
>>> time_max
array([ 82.5 , 20. , 113.75, 51.25])
>>> data_max
array([ 0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
>>> np.all(data_max == data.max(axis=0))
True
使用布尔数组建立索引,通过这样快速提取所需部分内容
>>> a = np.arange(12).reshape(3,4)
>>> b = a > 4
>>> b # b is a boolean with a's shape
array([[False, False, False, False],
[False, True, True, True],
[ True, True, True, True]])
>>> a[b] # 1d array with the selected elements
array([ 5, 6, 7, 8, 9, 10, 11])
利用 Mandelbrot集生成图像
import numpy as np
import matplotlib.pyplot as plt
def mandelbrot( h,w, maxit=20 ):
"""Returns an image of the Mandelbrot fractal of size (h,w)."""
y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
c = x+y*1j
z = c
divtime = maxit + np.zeros(z.shape, dtype=int)
for i in range(maxit):
z = z**2 + c
diverge = z*np.conj(z) > 2**2 # who is diverging
div_now = diverge & (divtime==maxit) # who is diverging now
divtime[div_now] = i # note when
z[diverge] = 2 # avoid diverging too much
return divtime
plt.imshow(mandelbrot(400,400))
如果在pycharm上跑的话,别忘了加上一句
plt.show()
效果:
ix_()函数
>>> a = np.array([2,3,4,5])
>>> b = np.array([8,5,4])
>>> c = np.array([5,4,6,8,3])
>>> ax,bx,cx = np.ix_(a,b,c)
>>> ax
array([[[2]],
[[3]],
[[4]],
[[5]]])
>>> bx
array([[[8],
[5],
[4]]])
>>> cx
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
>>> result = ax+bx*cx
>>> result
array([[[42, 34, 50, 66, 26],
[27, 22, 32, 42, 17],
[22, 18, 26, 34, 14]],
[[43, 35, 51, 67, 27],
[28, 23, 33, 43, 18],
[23, 19, 27, 35, 15]],
[[44, 36, 52, 68, 28],
[29, 24, 34, 44, 19],
[24, 20, 28, 36, 16]],
[[45, 37, 53, 69, 29],
[30, 25, 35, 45, 20],
[25, 21, 29, 37, 17]]])
>>> result[3,2,4]
17
>>> a[3]+b[2]*c[4]
17
线性代数
线性代数的处理主要在np.linalg模块中,如:
np.linalg.inv():矩阵求逆
np.linalg.det():矩阵求行列式(标量)
另外一些常用的方法(求特征值),参考这位老哥的文章