赞
踩
目录
1.2.4 ndarray.astype() #转换元素类型
1.2.5 np.set_printoptions(precision = ) #控制小数点位数
1.3.4 np.zeros()、np.ones()、np.empty()、np.full() #特殊数组
1.3.5 np.zeros_like()、np.ones_like()、np.empty_like()、np.full_like() #形状相同的特殊数组
1.4.3 np.compress() #通过布尔数组获取元素
2.2.2 布尔运算(np.logical_and、or、not)
2.4.2 np.broadcast_arrays() #查看广播之后的数组
2.5.1 np..reduce() #对数组内元素四则运算
2.5.2 np..accumulate() #对数组内元素四则运算
2.5.3 np..reduceat() 计算多组reduce()的结果
4.1.1 np.random.rand()(产生随机0~1浮点数)
4.1.2 np.random.randn()(产生正态分布随机数)
4.1.3 np.random.randint()(产生随机整数)
4.1.4 np.random.normal()(随正态分布)
4.1.5 np.random.uniform()(均匀分布)
4.1.6 np.random.possion()(泊松分布)
4.1.7 np.random.permutation() #产生乱序数组、打乱数组
4.1.8 np.random.shuffle() #打乱数组
4.1.9 np.random.choice() #随机抽取
4.3.1 np.min(),np.max(),np.minimum(),np.maximum(),np.ptp()
4.3.2 np.argmax(),np.argmin() #求最值下标
4.3.3 np.unravel_index() #下标转化
4.3.6 np.lexsort() 应用:成绩姓名全局排序
4.3.7 np.partition(),np.argpartition() #数组分割
4.3.10 np.searchsorted() #插入元素(二分查找)
4.4.2 np.bincount() #对整数数组的元素计数
4.6.1 np.concatenate() #连接多个数组
4.6.5 np.split()、np.array_split() #将数组分为多段
4.6.6 np.transpose()、np.swapaxes() #重新设置轴的顺序
4.7.1 np.poly1d() #转化成poly1d对象
4.8.1 np.polynomial.Polynomial() #创建Polynomial对象
4.8.3 np.polynomial.Chebyshev()(拓展)
NumPy提供了两种基本的对象:
1.ndarry:储存单一数据类型的多维数组
2.nfunc:对数组进行处理的特殊函数
查看numpy库的版本:
- import numpy
- print(numpy.__version__)
'运行
结果如下:
1.19.2
用np.array()创建数组,括号中可以是列表、元组、多维列表:
- import numpy as np
-
- a = np.array([1,2,3])
- b = np.array((1,2,3))
- c = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
-
- print(a)
- print(b)
- print(c)
'运行
结果如下:
- [1 2 3]
- [1 2 3]
- [[ 1 2 3 4]
- [ 5 6 7 8]
- [ 9 10 11 12]]
用ndarray.shape可获得数组的形状,返回元组(几行,几列):
- import numpy as np
-
- a = np.array([1,2,3])
- b = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
-
- print(a.shape)
- print(b.shape)
'运行
结果如下:
- (3,)
- (3, 4)
'运行
用ndarray.reshape(x,y)可以改变数组形状:
- import numpy as np
-
- a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
- print(a)
-
- b = a.reshape(2,6)
- print(b)
'运行
结果如下:
- [[ 1 2 3 4]
- [ 5 6 7 8]
- [ 9 10 11 12]]
- [[ 1 2 3 4 5 6]
- [ 7 8 9 10 11 12]]
(ps.b是通过a的转化得来,因此在这之后对a操作也会引起b的变化,示例如下:)
- import numpy as np
-
- a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
-
- b = a.reshape(2,6)
-
- a[0][0] = 100
-
- print(a)
- print(b)
'运行
结果如下:
- [[100 2 3 4]
- [ 5 6 7 8]
- [ 9 10 11 12]]
- [[100 2 3 4 5 6]
- [ 7 8 9 10 11 12]]
ndarray.dtype可以得到数组元素的类型:
- import numpy as np
-
- a = np.array([1,2,3])
-
- print(a.dtype)
'运行
结果如下:
int32
即32位的长整型(默认值与操作系统和Python有关)
astype()方法可以对数组的元素类型进行转换:
- import numpy as np
-
- a = np.array([1,2,3])
- b = a.astype(np.float)
- c = a.astype(np.complex)
-
- print(b.dtype)
- print(b)
-
- print(c.dtype)
- print(c)
结果如下:
- float64
- [1. 2. 3.]
- complex128
- [1.+0.j 2.+0.j 3.+0.j]
该函数可以控制输出的数组中显示小数点位数
(set_printoptions()里还有很多参数,在此仅说明precision的意义)
- import numpy as np
-
- np.set_printoptions(precision = 3) #四舍五入保留三位小数
-
- a = np.array([0.12345,2.54687])
- print(a)
'运行
结果如下:
[0.123 2.547]
np.arange(start, stop, step)可以创建等差数列的一维数组,其中开始值和终值遵循“左闭右开”的原则,类似于list中的range()
- import numpy as np
-
- a = np.arange(0,1,0.1)
-
- print(a)
'运行
结果如下:
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
np.linspace(start, stop, number, endpoint = )中可以指定开始值、终值和元素个数,可以通过endpoint参数指定是否包含终值,endpoint = True 则包含终值(默认为True)
- import numpy as np
-
- a = np.linspace(0,1,10,endpoint = False)
-
- print(a)
'运行
结果如下:
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
np.logspace()与np.linspace()相似,其start和stop为10的幂,例如(0,3,3)表示从开始到,元素数量为4的等比数列:
- import numpy as np
-
- a = np.logspace(0,3,4)
-
- print(a)
'运行
结果如下:
[ 1. 10. 100. 1000.]
np.zeros():创建制定形状的全零数组
np.ones():创建制定形状的全一数组
np.empty():只分配数组所使用的内存
np.full():将元素初始化为指定的值
- import numpy as np
-
- a = np.zeros((2,3),int)
- b = np.ones((2,3),int)
- c = np.empty((2,3),float)
- d = np.full((2,3),666)
-
- print(a)
- print(b)
- print(c)
- print(d)
'运行
结果如下:
- [[0 0 0]
- [0 0 0]]
- [[1 1 1]
- [1 1 1]]
- [[1. 1.1 1.2]
- [9.7 9.8 9.9]]
- [[666 666 666]
- [666 666 666]]
括号中输入数组,创建与输入数组相同形状的全零数组、全一数组等等
以np.zeros_like()为例:
- import numpy as np
-
- a = [[1,2,3,4],[5,6,7,8]]
- print(a)
-
- b = np.zeros_like(a)
- print(b)
'运行
结果如下:
- [[1, 2, 3, 4], [5, 6, 7, 8]]
- [[0 0 0 0]
- [0 0 0 0]]
与列表(list)中操作相同,不再赘述
两个[[ ]]中填入需要的元素下标,该操作可以提取ndarry指定下标的元素并组成一个新的数组:
- import numpy as np
-
- a = np.arange(10,20,1)
- print(a)
-
- b = a[[2,4,6,8]]
- print(b)
'运行
结果如下:
- [10 11 12 13 14 15 16 17 18 19]
- [12 14 16 18]
这种方法中,可以理解为:b是将a中元素提取后重新创建的一个数组,因此a和b不共用内存,所以对a操作不会影响b,a和b是相互独立的,互不影响。
ndarray[[ ]]也可以快速修改指定下标位置处元素的值:
- import numpy as np
-
- a = np.arange(0,10,1)
- print(a)
-
- a[[2,4,6,8]] = 0,0,0,0
- print(a)
'运行
结果如下:
- [0 1 2 3 4 5 6 7 8 9]
- [0 1 0 3 0 5 0 7 0 9]
沿着指定轴获取元素
- import numpy as np
-
- a = np.arange(3*4).reshape(3,4)
- print(a)
-
- result = a.take(indices = 0,axis = 1)
- print(result)
'运行
结果如下:
- [[ 0 1 2 3]
- [ 4 5 6 7]
- [ 8 9 10 11]]
-
- [0 4 8]
即:沿着axis = 1(纵轴)取第0列元素
沿着指定轴通过布尔数组获取元素
np.compress(condition, ndarray, axis = )
- import numpy as np
-
- a = np.array([0,1,-2,0,3])
- print(a)
-
- b = np.compress([1,0,1],a,axis = 0)
- print(b)
-
- c = np.compress([1,0,1,0,1],a,axis = 0)
- print(c)
'运行
结果如下:
- [ 0 1 -2 0 3]
- [ 0 -2]
- [ 0 -2 3]
即在数组a中,沿着axis = 0的轴(横轴),取布尔数组中真值对应下标的元素
二维数组的创建实际上是一个加法表,由纵向量和横向量的元素相加而得,例如:
- import numpy as np
-
- a = np.arange(0,60,10).reshape(-1,1)
- b = np.arange(0,6)
-
- print(a)
- print(b)
- print(a+b)
'运行
结果如下:
- [[ 0]
- [10]
- [20]
- [30]
- [40]
- [50]]
- [0 1 2 3 4 5]
- [[ 0 1 2 3 4 5]
- [10 11 12 13 14 15]
- [20 21 22 23 24 25]
- [30 31 32 33 34 35]
- [40 41 42 43 44 45]
- [50 51 52 53 54 55]]
- import numpy as np
-
- a = np.arange(0,60,10).reshape(-1,1) + np.arange(0,6)
- print(a)
- print('\n')
-
- print(a[0,3:5]) #表示第0行的第3到5个元素
- print('\n')
-
- print(a[4:,4:]) #第4行之后及第4列之后元素组成的数组
- print('\n')
-
- print(a[:,2]) #每一行的第二个元素组成的列表
- print('\n')
-
- print(a[2::2,::2])
'运行
结果如下:
- [[ 0 1 2 3 4 5]
- [10 11 12 13 14 15]
- [20 21 22 23 24 25]
- [30 31 32 33 34 35]
- [40 41 42 43 44 45]
- [50 51 52 53 54 55]]
-
-
- [3 4]
-
-
- [[44 45]
- [54 55]]
-
-
- [ 2 12 22 32 42 52]
-
-
- [[20 22 24]
- [40 42 44]]
需要注意的是,b = a[0,3:5]这样的切片中,b是a的视图,他们共享数据,因此,改变a会对b造成影响
创建一个dtype对象person,其参数是字典,键:'names','formats',
其中names定义结构中每个字段的名称;formats定义每个字段的类型:
'S30':长度为30个字节的字符串类型,(必须指明其长度)
'i':32位的整数类型,相当于'np.int32'
'f':32位的单精度浮点型,相当于'np.float32'
然后调用array()创建数组,通过dtype参数来制定创建的数组的元素类型为person
- import numpy as np
-
- person = np.dtype({
- 'names':['name','age','height'], #'names'是固定名称,不可更改,但name、age等可更改
- 'formats':['S30','i','f']}, #'formats'是固定名称,不可更改
- align = True)
-
- a = np.array([('Jia',20,177),('Zhang',19,159)],dtype = person)
-
- print(a)
-
- print(a.dtype)
'运行
结果如下:
- [(b'Jia', 20, 177.) (b'Zhang', 19, 159.)]
-
- {'names':['name','age','height'], 'formats':['S30','<i4','<f4'],
- 'offsets':[0,32,36], 'itemsize':40, 'aligned':True}
其中'<i4','<f4'的'<'表示低位字节在前,即小端模式(little endian);'>'表示高位字节在前,即大端模式(big endian);不显示则表示忽略字节顺序。
结构数组的存取和一般数组相同,通过下标就能获取:
- import numpy as np
-
- person = np.dtype({
- 'names':['name','age','height'],
- 'formats':['S30','i','f']},
- align = True)
-
- a = np.array([('Jia',20,177),('Zhang',19,159)],dtype = person)
-
- print(a[0])
'运行
结果如下:
(b'Jia', 20, 177.)
'运行
需要注意的是,输出的结果长得像元组,但并不是元组,而是结构:
print(a[0].dtype)
结果如下:
- {'names':['name','age','height'], 'formats':['S30','<i4','<f4'],
- 'offsets':[0,32,36], 'itemsize':40, 'aligned':True}
'运行
因此可以用字段名作为下标获取相应元素,也可以通过这种方法修改元素:
print(a[0]['name'])
结果如下:
b'Jia'
'运行
表达式 | 对应的ufunc函数 |
y = x1 + x2 | add(x1, x2 [ ,y]) |
y = x1 - x2 | subtract(x1, x2 [ ,y]) |
y = x1 * x2 | multiply(x1, x2 [ ,y]) |
y = x1 / x2 | divide(x1, x2 [ ,y]),如果两个数组的元素为整数,则用整数除法 |
y = x1 / x2 | true_divide(x1, x2 [ ,y]),总是返回精确的商 |
y = x1 // x2 | floor_divide(x1, x2 [ ,y]),总是对返回值取整 |
y = -x | negative(x [ ,y]) |
y = x1 ** x2 | power(x1, x2 [ ,y]) |
y = x1 % x2 | remainder(x1, x2 [ ,y]),mod(x1, x2 [ ,y]) |
用符号也可以直接运算:
- import numpy as np
-
- a = np.array([1,2,3])
- b = np.array([3,2,1])
-
- print(a+b)
- print(a-b)
- print(a*b)
- print(a/b)
- print(a//b)
- print(-a)
- print(a**b)
- print(a%b)
'运行
结果如下:
- [4 4 4]
- [-2 0 2]
- [3 4 3]
- [0.33333333 1. 3. ]
- [0 1 3]
- [-1 -2 -3]
- [1 4 3]
- [1 0 0]
比较两个数组的对应元素,如果满足要求则不二数组对应位置为True,否则为False
表达式 | 对应的ufunc函数 |
x1 == x2 | equal(x1, x2 [ ,y]) |
x1 != x2 | not_equal(x1, x2 [ ,y]) |
x1 < x2 | less(x1, x2 [ ,y]) |
x1 <= x2 | less_equal(x1, x2 [ ,y]) |
x1 > x2 | greater(x1, x2 [ ,y]) |
x1 >= x2 | greater_equal(x1, x2 [ ,y]) |
用符号也可以直接运算:
- import numpy as np
-
- a = np.array([1,2,3])
- b = np.array([3,2,1])
-
- print(a == b)
- print(a != b)
- print(a < b)
- print(a <= b)
- print(a > b)
- print(a >= b)
'运行
结果如下:
- [False True False]
- [ True False True]
- [ True False False]
- [ True True False]
- [False False True]
- [False True True]
Python中布尔运算使用and、or、not关键字,无法被重载,因此数组的布尔运算只能通过相应的ufunc函数进行,他们都以“logical_”开头:logical_and()、logical_or()、logical_not()
- import numpy as np
-
- a = np.array([1,2,3])
- b = np.array([3,2,1])
-
- print(np.logical_and(a > b,a == b))
'运行
结果如下:
[False False False]
NumPy中也定义了np.any()和np.all()
np.any():只要有一个元素为True就返回True
np.all():只有当全部元素都为True才返回True
- import numpy as np
-
- a = np.array([0,1,2,3])
-
- print(np.all(a))
- print(np.any(a))
'运行
结果如下:
- False
- True
'运行
通常情况下,自定义(def)出的函数只能计算单个值
例如:定义一个分段函数,小于-10时输出-1,在-10到10之间输出0,大于10输出1。
- def f(a,b,x):
- if x <= a:
- return -1
- if a < x <b:
- return 0
- if x >= b:
- return 1
-
- c = 6
- result = f(-10,10,c)
- print(result)
'运行
结果如下:
0
'运行
但如果此时c不再是一个数字,而是一串数字,例如列表、数组,这种函数就不能直接计算,只能多次调用,单独计算。通过np.frompyfunc()可以将计算单个值的函数转化为能对数组的每个元素进行计算的ufunc函数。
np.frompyfunc()的调用格式为:np.frompyfunc(func, nin, nout)。其中func:计算单个值的函数;nin:func中输入参数的个数;nout:func中返回值的个数。(注意:np.frompyfunc()只起到转换函数的作用,需要计算时要重新调用)
例如:定义一个分段函数,小于-10时输出-1,在-10到10之间输出0,大于10输出1
- import numpy as np
-
- def f(a,b,x):
- if x <= a:
- return -1
- if a < x <b:
- return 0
- if x >= b:
- return 1
-
- function = np.frompyfunc(f,3,1) #只起到转换函数的作用
-
- c = np.arange(-15,15,3)
- result = function(-10,10,c) #计算时重新调用function()函数
-
- print(c) #自变量
- print(result) #分段函数输出的结果
'运行
结果如下:
- [-15 -12 -9 -6 -3 0 3 6 9 12]
- [-1 -1 0 0 0 0 0 0 0 1]
使用ufunc函数对两个数组计算时,会对两个数组的对应元素进行计算,因此要求两个数组形状相同。如果不同,会进行广播(broadcasting)处理
①以维数最多的数组为准,其他数组向它看齐,shape属性中不足的部分通过在前面加1补齐;
②输出数组的shape属性是输入数组shape属性的各个轴上的最大值;
③如果输入数组的某个长度为1,或与输出数组的对应轴长度相同,则这个数组可以用来计算,否则出错;
④当输入数组的某个轴长度为1时,沿着该轴运算时,都用该轴上的第一组值。
具体实例:
先创建一个二维数组a,形状为(6, 1)
- import numpy as np
-
- a = np.arange(0,60,10).reshape(-1,1)
-
- print(a)
- print(a.shape)
'运行
结果如下:
- [[ 0]
- [10]
- [20]
- [30]
- [40]
- [50]]
- (6, 1)
再创建一维数组b,其形状为(5, ):
- import numpy as np
-
- a = np.arange(0,60,10).reshape(-1,1)
- b = np.arange(0,5)
-
- print(b)
'运行
结果如下:
[0 1 2 3 4]
计算a与b的和,得到一个加法表,相当于计算两个数组中所有元素对的和,得到一个形状为(6, 5)的数组:
- import numpy as np
-
- a = np.arange(0,60,10).reshape(-1,1)
- b = np.arange(0,5)
- c = a+b
-
- print(c)
'运行
结果如下:
- [[ 0 1 2 3 4]
- [10 11 12 13 14]
- [20 21 22 23 24]
- [30 31 32 33 34]
- [40 41 42 43 44]
- [50 51 52 53 54]]
由于a和b的维数不同,根据①,需要让b的shape属性向a对齐,于是在b的shape属性前补加1,变为(1, 5),即从 [0,1,2,3,4,5] 变成 [[0,1,2,3,4,5]],则a和b的shape变为(6, 1)和(1, 5),根据②,输出的数组长度为各个轴长度的最大值,则输出的c的shape属性为(6, 5)
由于b的第0轴(横着的,行)的长度为1,a的第0轴的长度为6,要把b的第0轴扩展成长度为6才能相加,即:
- [[0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]
- [0 1 2 3 4]]
对a同理,则可以保证形状相同,才能相加。
np.broadcast_arrays()可以查看广播之后的数组,返回广播后的多个数组
- import numpy as np
-
- a = np.arange(2*3).reshape(2,3)
- print(a)
- print(a.shape)
-
- b = np.array([1,2,3])
- print(b)
- print(b.shape)
-
- result = np.broadcast_arrays(a,b)
- print(result)
'运行
结果如下:
- [[0 1 2]
- [3 4 5]]
-
- (2, 3)
-
- [1 2 3]
-
- (3,)
-
- [array([[0, 1, 2],
- [3, 4, 5]]),
- array([[1, 2, 3],
- [1, 2, 3]])]
ndarray.repeat(复制的次数,axis = )
其中,axis = 0表示第0轴(列),即沿着axis = 0的轴,复制数组中各个元素的值
axis = 1表示第1轴(行),同理。
例1:对二维数组,沿第0轴复制
- import numpy as np
-
- a = np.array([[1,2,3,4,5]])
- print(a)
-
- c = a.repeat(3,axis = 0)
- print(c)
'运行
结果如下:
- [[1 2 3 4 5]]
-
- [[1 2 3 4 5]
- [1 2 3 4 5]
- [1 2 3 4 5]]
例2:对一维数组,沿第0轴复制
- import numpy as np
-
- a = np.array([1,2,3,4,5])
- print(a)
-
- c = a.repeat(3,axis = 0)
- print(c)
'运行
结果如下:
- [1 2 3 4 5]
- [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]
例3:对二维数组,沿第1轴复制
- import numpy as np
-
- a = np.array([[1,2,3,4,5]])
- print(a)
-
- c = a.repeat(3,axis = 1)
- print(c)
'运行
结果如下:
- [[1 2 3 4 5]]
- [[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]]
表示在None对应的位置创建一个长度为1的新轴,例如:a[None, :]和a.reshape(1, -1)等效
- import numpy as np
-
- a = np.array([1,2,3,4,5])
- print(a)
-
- print(a[None,:])
- print(a.reshape(1,-1))
- print(a[:,None])
'运行
结果如下:
- [1 2 3 4 5]
-
- [[1 2 3 4 5]]
-
- [[1 2 3 4 5]]
-
- [[1]
- [2]
- [3]
- [4]
- [5]]
ufunc方法本身还有一些函数,这些方法只对2个输入、1个输出的ufunc函数有效,其他的ufunc对象调用这些方法时会抛出ValueError异常
np.<op>.reduce(array, axis = , dtype = )
<op>是指运算符,例如add、subtract、multiple、divide等等,该方法沿着axis指定的轴对数组进行操作,相当于沿着axis轴,将<op>添加到数组的各个元素之间,输出计算结果,例如:
- import numpy as np
-
- a = np.array([1,2,3,4])
-
- b = np.add.reduce(a,axis=0) #1+2+3+4
- print(b)
-
- c = np.subtract.reduce(a,axis=0) #1-2-3-4
- print(c)
-
- d = np.multiply.reduce(a,axis=0) #1*2*3*4
- print(d)
'运行
结果如下:
- 10
- -8
- 24
'运行
accumulate与reduce类似,只是返回与输入形状相同的数组,保存所有的中间计算过程:
- import numpy as np
-
- a = np.array([1,2,3,4])
-
- b = np.add.accumulate(a,axis=0)
- print(b) #[1,1+2,1+2+3,1+2+3+4]
-
- c = np.subtract.accumulate(a,axis=0)
- print(c) #[1,1-2,1-2-3,1-2-3-4]
-
- d = np.multiply.accumulate(a,axis=0)
- print(d) #[1,1*2,1*2*3,1*2*3*4]
'运行
结果如下:
- [ 1 3 6 10]
- [ 1 -1 -4 -8]
- [ 1 2 6 24]
reduceat()方法计算多组reduce()的结果,通过indices参数指定一系列的起始和终止位置,例如:
- import numpy as np
-
- a = np.array([1,2,3,4])
-
- result = np.add.reduceat(a,indices = [0,1,0,2,0,3,0])
- print(result)
'运行
结果如下:
[ 1 2 3 3 6 4 10]
对于indices的每一个值,都会计算出一个值,结果中除了最后一个参数外,计算过程如下:
- if indices[i] < indices[i+1]: #如果该元素小于后面一个元素
- result[i] = <op>.reduce(a[indices[i]:indices[i+1]])
-
- else: #如果该元素不小于后面一个元素
- result[i] = a[indices[i]]
对于最后一个元素,计算过程如下:
<op>.reduce(a[indices[-1]:])
np.<op>.outer(a,b),其结果是一个计算表(加法表,乘法表,减法表),例如:
- import numpy as np
-
- a = np.array([1,2,3,4,5])
- b = np.array([2,3,4])
-
- result = np.multiply.outer(a,b)
- print(result)
'运行
结果如下:
- [[ 2 3 4]
- [ 4 6 8]
- [ 6 9 12]
- [ 8 12 16]
- [10 15 20]]
相当于是乘法表(加法,减法同理):
- 2 3 4
- ----------
- 1| 2 3 4
- 2| 4 6 8
- 3| 6 9 12
- 4| 8 12 16
- 5| 10 15 20
多维数组的下标是一个“ 长度 = 数组维度 ”的数组,
如果下标的长度 > 数组维数,则会出错;
如果下标长度 < 数组维数,则会在下标元组后面补“ : ”,使得长度和维数相同。
----------------------------------------------------------------------
如果下标对象不是元组,NumPy会先把他转化成元组,但这个过程可能与用户想的有出入,例如:a是一个三维数组,分别用 二维列表 和 二维数组 作为下标,输出是不一样的:
- import numpy as np
-
- a = np.arange(3*4*5).reshape(3,4,5)
- print(a) #三维数组
-
- b = tuple([[0],[1]]) #二维元组
- c = np.array([[0],[1]]) #二维数组
-
- print(a[b])
- print(a[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 24]
- [25 26 27 28 29]
- [30 31 32 33 34]
- [35 36 37 38 39]]
-
- [[40 41 42 43 44]
- [45 46 47 48 49]
- [50 51 52 53 54]
- [55 56 57 58 59]]]
-
-
- [[5 6 7 8 9]]
-
-
- [[[[ 0 1 2 3 4]
- [ 5 6 7 8 9]
- [10 11 12 13 14]
- [15 16 17 18 19]]]
-
- [[[20 21 22 23 24]
- [25 26 27 28 29]
- [30 31 32 33 34]
- [35 36 37 38 39]]]]
如果下标元组的所有元素都是切片和整数,那么用它作为下标的得到的是原始数组的一个视图,即它和原始数组共享数据空间
布尔数组作为下标对象时,相当于用nonzero()将布尔数组转化成一组整数数组,然后用整数数组进行下标运算
np.nonzero()返回数组中元素不为零的值的下标组成的数组,例如:
- import numpy as np
-
- a = np.array([0,1,-2,0,3])
- print(a)
-
- b = np.nonzero(a)
- print(b)
'运行
结果如下:
- [ 0 1 -2 0 3]
- (array([1, 2, 4], dtype=int64),)
笔记函数总览:
函数名 | 功能 | 函数名 | 功能 |
rand | 0到1之间的随机数 | randn | 标准正态分布的随机数 |
randint | 指定范围内的随机整数 | normal | 正态分布 |
uniform | 均匀分布 | poisson | 泊松分布 |
permutation | 随机排列 | shuffle | 随机打乱顺序 |
choice | 随机抽取样本 | seed | 设置随机数种子 |
产生0到1之间的随机浮点数,所有参数用于指定所产生数组的形状
- import numpy as np
-
- a = np.random.rand()
- print(a)
-
- b = np.random.rand(2,3)
- print(b)
'运行
结果如下:
- 0.26454873391353306
-
- [[0.32604263 0.61228564 0.92722863]
- [0.3631769 0.53571405 0.04554973]]
产生服从标准正态分布的随机数,参数含义与rand()相同
- import numpy as np
-
- a = np.random.randn()
- print(a)
-
- b = np.random.randn(2,3)
- print(b)
'运行
结果如下:
- -0.07751610157473836
- [[ 0.20687204 0.41934397 -0.80796835]
- [ 0.44276644 0.84450041 -0.41650222]]
产生指定范围内的随机整数,范围左闭右开
np.random.randint(start, stop, shape)
参数分别指定:起始值,终值,产生数组的形状(若没有这一项则默认返回一个随机整数)
- import numpy as np
-
- b = np.random.randint(0,10)
- print(b)
-
- c = np.random.randint(0,10,(2,3))
- print(c)
'运行
结果如下:
- 3
-
- [[5 8 9]
- [5 2 3]]
正态分布,其参数有三个,分别是:期望值、标准差、形状。例如:
- import numpy as np
-
- a = np.random.normal(100,10)
- print(a)
-
- b = np.random.normal(100,10,(2,3))
- print(b)
'运行
结果如下:
- 97.37335368991738
-
- [[ 99.207 88.422 113.329]
- [100.994 81.526 99.495]]
均匀分布,其参数有三个,分别是:起始值、终值、形状。例如:
- import numpy as np
-
- a = np.random.uniform(10,20)
- print(a)
-
- b = np.random.uniform(10,20,(2,3))
- print(b)
'运行
结果如下:
- 17.06049626065125
- [[16.817 16.852 14.206]
- [13.688 15.58 18.359]]
泊松分布,其参数有两个,分别是:系数(单位时间或单位面积内随机事件的平均发生率)、形状。例如:
- import numpy as np
-
- a = np.random.poisson(2)
- print(a)
-
- b = np.random.poisson(2,(2,3))
- print(b)
'运行
结果如下:
- 2
-
- [[2 1 0]
- [2 1 4]]
产生一个乱序数组
当参数为整数n时,他返回 [0, n) 这n个整数的随机排列;
当参数为一个序列时,他返回这个序列的随机排列。
- import numpy as np
-
- r1 = np.random.permutation(6) #生成乱序数组
- print(r1)
-
- a = np.array([11,12,13,14,15,16]) #打乱数组
- r2 = np.random.permutation(a)
- print(r2)
'运行
结果如下:
- [3 0 1 2 5 4]
- [12 11 16 13 15 14]
将指定数组打乱,与permutation的区别是:
permutation将原数组中的元素打乱后放入新的数组中(产生了新的数组),对原数组没有影响;
shuffle直接改变原数组,将原数组打乱(不能产生新数组),是对原数组的操作,不能将其赋给新的变量
- import numpy as np
-
- a = np.array([11,12,13,14,15,16])
-
- r1 = np.random.permutation(a)
- print(r1)
- print(a)
-
- np.random.shuffle(a)
- print(a)
'运行
结果如下:
- [11 16 14 15 12 13] # a打乱后赋值给r1
-
- [11 12 13 14 15 16] # a没有改变
-
- [16 12 13 14 15 11] # a被改变
从指定样本中随机抽取
np.random.choice(ndarray, size = , replace = , p = )
size:用于指定输出数组的形状
replace:replace = True(默认)时,进行放回抽取;否则进行不放回抽取
p:指定每个元素的抽取概率(以列表或数组形式),如果不指定则默认为等概率抽取
当参数只有ndarray时,则返回随机抽取的一个数
- import numpy as np
-
- a = np.arange(10)
-
- r1 = np.random.choice(a)
- print(r1)
-
- r2 = np.random.choice(a,size = (2,3),replace = True,p = a/np.sum(a))
- print(r2)
'运行
结果如下:
- 2
-
- [[1 7 5]
- [8 7 2]]
保证每次运行时出现相同的随机数,可以通过seed()指定随机数的种子
调用格式为:np.random.seed(num)
- import numpy as np
-
- np.random.seed(2)
-
- a = np.random.rand()
- print(a)
'运行
结果如下:
0.43599490214200376(运行无数次都是这个结果)
函数总览:
函数名 | 功能 | 函数名 | 功能 |
sum | 求和 | mean | 求期望 |
average | 加权平均数 | std | 标准差 |
var | 方差 | product | 连乘积 |
对指定元素进行求和,可以对所有元素求和,沿行(列)求和,对指定轴求和
- import numpy as np
-
- a = np.arange(2*3).reshape(2,3)
- print(a)
-
- r1 = np.sum(a) #对所有元素求和
- r2 = np.sum(a,axis = 0) #沿着行方向,对a的每一列求和
- r3 = np.sum(a,axis = 1,dtype = float) #沿着列方向,对a的每一行求和
-
- print(r1)
- print(r2)
- print(r3)
'运行
结果如下:
- [[0 1 2]
- [3 4 5]]
-
- 15
-
- [3 5 7]
-
- [ 3. 12.]
求数组的平均值,参数与sum()相同
- import numpy as np
-
- a = np.arange(2*3).reshape(2,3)
- print(a)
-
- r1 = np.mean(a)
- r2 = np.mean(a,axis = 0)
-
- print(r1)
- print(r2)
'运行
结果如下:
- [[0 1 2]
- [3 4 5]]
-
- 2.5
-
- [1.5 2.5 3.5]
average()也可以进行平均计算,特殊点在于:他有一个weights参数,可以计算加权平均数
- import numpy as np
-
- score = np.array([88,90,93])
- number = np.array([15,25,30])
-
- result = np.average(score,weights = number)
- print(result)
'运行
结果如下:
90.85714285714286
'运行
计算数组的标准差
np.std(ndarray, axis = , dtype= , out = , ddof= )
ddof = 0(默认)时,计算偏样本标准差;ddof = 1时,计算无偏样本标准差
- import numpy as np
-
- a = np.array([1,2,3,4,5,6])
-
- r1 = np.std(a,axis = 0, ddof = 0)
- r2 = np.std(a,axis = 0, ddof = 1)
-
- print(r1)
- print(r2)
'运行
结果如下:
- 1.707825127659933
- 1.8708286933869707
'运行
计算数组的方差,参数与np.std()一样
- import numpy as np
-
- a = np.array([1,2,3,4,5,6])
-
- r1 = np.var(a,axis = 0, ddof = 0)
- r2 = np.var(a,axis = 0, ddof = 1)
-
- print(r1)
- print(r2)
'运行
结果如下:
- 2.9166666666666665
- 3.5
'运行
计算数组中所有元素的乘积
参数与np.sum()类似
- import numpy as np
-
- a = np.array([1,2,3,4,5,6])
-
- r1 = np.product(a)
- print(r1)
'运行
结果如下:
720
'运行
函数总览
函数名 | 功能 | 函数名 | 功能 |
min | 最小值 | max | 最大值 |
minimum | 二元最小值 | maximum | 二元最大值 |
ptp | 极差 | argmin | 最小值的下标 |
argmax | 最大值的下标 | unravel_index | 一维下标转化成多维下标 |
sort | 数组排序 | argsort | 计算数组排序的下标 |
lexsort | 多列排序 | partition | 快速计算前k位 |
argpartition | 前k位的下标 | median | 中位数 |
percentile | 百分位数 | searchsorted | 二分查找 |
np.min(),np.max(),np.minimum(),np.maximum()分别表示计算最小值、最大值、二元最小值、二元最大值、极差
前四个函数的用法与np.sum()类似,np.ptp()有axis和out参数,用法与之前类似,这里例举最简单的情况:
- import numpy as np
-
- a = np.array([-1,6,4,-7,3,4])
- b = np.arange(2*3).reshape(2*3)
-
- print(a)
- r1 = np.min(a)
- r2 = np.max(a)
- r3 = np.ptp(a)
- print(r1)
- print(r2)
- print(r3)
-
- print(b)
- r4 = np.minimum(a,b) #对比a和b对应位置的元素,选出两个中最小的一个,放入新数组的对应位置
- r5 = np.maximum(a,b)
- r6 = np.ptp(b)
- print(r4)
- print(r5)
- print(r6)
'运行
结果如下:
- [-1 6 4 -7 3 4] #a
- -7 #min
- 6 #max
- 13 #max-min
-
- [0 1 2 3 4 5] #b
- [-1 1 2 -7 3 4] #minimum
- [0 6 4 3 4 5] #maximum
- 5 #maximum-minimum
可以求最大值和最小值的下标
如果不指定axis参数,则返回平坦化(转化成一维数组)之后的数组下标
如果指定axis参数,可以沿着指定轴计算最大值的下标
- import numpy as np
-
- a = np.random.randint(0,10,size = (2,3))
- r1 = np.argmax(a)
- print(a)
- print(r1)
'运行
结果如下:
- [[8 9 0]
- [1 1 4]]
- 1
可以将一维数组下标转化成多维数组的下标
np.unracel_index(下标, 多维数组的形状)
- import numpy as np
-
- a = np.random.randint(0,10,size = (2,3))
- r1 = np.argmax(a)
- print(a) #输出数组a
- print(r1) #最大值在数组平坦化后的下标
-
- r2 = np.unravel_index(r1,a.shape)
- print(r2) #最大值在原数组形状下的下标
'运行
结果如下:
- [[6 0 1]
- [0 2 7]]
-
- 5
-
- (1, 2)
np.sort()可以对数组进行排序,并将排序后的值赋给新的数组
默认axis = 1(对每行数组进行排序)
axis = 0表示对每列数组进行排序
axis = None表示,将数组平坦化后进行排序
- import numpy as np
- np.random.seed(1)
-
- a = np.random.randint(0,10,size = (3,4))
- print(a)
-
- r1 = np.sort(a)
- r2 = np.sort(a,axis = 1)
- r3 = np.sort(a,axis = 0)
- r4 = np.sort(a,axis = None)
- print(r1)
- print(r2)
- print(r3)
- print(r4)
'运行
结果如下:
- [[5 8 9 5]
- [0 0 1 7]
- [6 9 2 4]] #a
-
- [[5 5 8 9]
- [0 0 1 7]
- [2 4 6 9]] #r1
-
- [[5 5 8 9]
- [0 0 1 7]
- [2 4 6 9]] #r2
-
- [[0 0 1 4]
- [5 8 2 5]
- [6 9 9 7]] #r3
-
- [0 0 1 2 4 5 5 6 7 8 9 9] #r4
np.argsort()返回数组的排序下标,参数axis默认为-1
- import numpy as np
- np.random.seed(69)
-
- a = np.random.randint(0,10,size = (5,))
- print(a)
-
- r1 = np.argsort(a)
- print(r1)
'运行
结果如下:
- [6 9 7 4 1]
- [4 3 0 2 1]
即:a中1是最小的,其下标是4,所以4在r1[0];
以此类推,4是a中第二小的,其下标为3,所以3在r1[1]
np.lexsort()类似于Excel中的多列排序,其参数为一个形状为(k, N)的数组,即包含k个长度为N的序列,可以理解成N行k列的表格,该方法返回排序下标,数组中最后的行为排序的主键(以数组中最后一行为标准进行排列)
例如:
- import numpy as np
- np.random.seed(69)
-
- name = ['A','B','C','D','E']
- age = [31,35,40,29,25]
-
- r1 = np.lexsort([name,age]) #参数是一个2行5列的数组
- print(r1)
'运行
结果如下:
[4 3 0 1 2]
即,以最后一行(age)为标准进行排序,所以返回age的下标排序
背景:A、B等5人乘积分别是95,93,87,99,96,将姓名与成绩对应,并按成绩由大到小排列
- import numpy as np
- np.random.seed(69)
-
- name = ['A','B','C','D','E']
- score = [95,93,87,99,96]
-
- idx = np.lexsort([name,score])
- print(idx)
-
- r1 = list(zip(name,score))
- l = []
- for i in idx:
- l.append(r1[i])
-
- print(l)
'运行
结果如下:
- [2 1 0 4 3]
- [('C', 87), ('B', 93), ('A', 95), ('E', 96), ('D', 99)]
np.partition(),np.argpartition()可以对数组进行分割,快速找出排序后数组的前k个元素(调用速度比sort()快很多)
np.partition(ndarray, kth = )
调用后,使新数组前kth个元素是原数组中最小的kth个,且这kth个也不按大小排序,只是把他们挑出来放在新数组的前面而已,剩余的放在后面随便排,例如:
- import numpy as np
- np.random.seed(69)
-
- a = np.random.randint(0,10,size = (10,))
- print(a)
-
- r1 = np.partition(a,kth = 7)
- print(r1)
'运行
结果如下:
- [6 9 7 4 1 6 9 8 1 6]
- [6 1 1 4 6 7 6 8 9 9]
即:r1的前7个元素是a中最小的7个,且在r1中没有按大小排序,只是把它们挑出来放在前七个位置上而已,后面的8,9,9是随便排的
如果需要将前7个排序,再调用一下np.sort()就可以:
- import numpy as np
- np.random.seed(69)
-
- a = np.random.randint(0,10,size = (10,))
- print(a)
-
- r1 = np.partition(a,kth = 7)
- print(r1)
-
- r2 = np.sort(r1[:7])
- print(r2)
'运行
结果如下:
- [6 9 7 4 1 6 9 8 1 6]
- [6 1 1 4 6 7 6 8 9 9]
- [1 1 4 6 6 6 7]
np.argpartition()同理,只是返回的是下标而已:
- import numpy as np
- np.random.seed(69)
-
- a = np.random.randint(0,10,size = (10,))
- print(a)
-
- r1 = np.argpartition(a,kth = 7)
- print(r1)
-
- r2 = np.sort(a[r1[:7]])
- print(r2)
'运行
结果如下:
- [6 9 7 4 1 6 9 8 1 6]
- [5 4 8 3 0 2 9 7 6 1]
- [1 1 4 6 6 6 7]
np.median()可以获得数组的中值,即:先把数组排序,再取中值。当长度是偶数时,取中间两个数的平均数
可以指定axis参数
- import numpy as np
- np.random.seed(69)
-
- a = np.random.randint(0,5,size = (5,))
- print(np.sort(a))
- r1 = np.median(a)
- print(r1)
-
- b = np.random.randint(0,6,size = (6,))
- print(np.sort(b))
- r2 = np.median(b)
- print(r2)
'运行
结果如下:
- [1 2 3 3 4]
- 3.0
- [0 0 0 1 1 1]
- 0.5
np.percentile()用于计算百分数,即:将元素从小大到排列,计算处于p%位置上的值
调用格式及参数:np.percentile(ndarray, p),其中p可以是一个数,也可以是一个数组
- import numpy as np
-
- a = np.array([1,2,3,4,5,6,7,8,9,10])
- print(a)
-
- r1 = np.percentile(a,[0,25,50,75,100])
- print(r1)
'运行
结果如下:
- [ 1 2 3 4 5 6 7 8 9 10]
- [ 1. 3.25 5.5 7.75 10. ]
searchsorted(a, value, side='left')
a:已经排好序的升序数组(如果a不是升序的,则该方法会先将a升序排列)
value:插入数组a的值,可以是单个元素、列表、数组
side:可以填入‘left‘或‘right‘。left则返回第一个符合条件的元素下标;right则返回最后一个符合条件的元素下标,如果没有符合的元素,则返回0或N(数组a的长度),即应该插入到a的最开始或最末尾
若a中有value中的元素(假设该元素为i):
当side = left(默认)时:直接返回a中第一个i的下标
当side = right时:返回a中最后一个i的下标并+1
- import numpy as np
-
- a = np.array([2,2,2,2,4,8,16,32])
- print(a)
-
- r1 = np.searchsorted(a,2,side = 'left')
- print(r1)
-
- r2 = np.searchsorted(a,2,side = 'right')
- print(r2)
'运行
结果如下:
- [ 2 2 2 2 4 8 16 32]
- 0
- 4
若a中没有value中的元素:
将value的各个元素插入到a的合适位置,使插入后的元素value满足:
当side = left(默认)时:a[i-1] < value <= a[i](局部升序)
当side = right时:a[i-1] <= value < a[i](局部升序)
- import numpy as np
-
- a = np.array([2,4,8,16,32])
- print(a)
-
- r1 = np.searchsorted(a,[1,3,5,7,9,11])
- print(r1)
-
- r2 = np.searchsorted(a,[1,3,5,7,9,11],side = 'right')
- print(r2)
'运行
结果如下:
- [ 2 4 8 16 32]
- [0 1 2 2 3 3]
- [0 1 2 2 3 3]
函数总览:
函数名 | 功能 | 函数名 | 功能 |
unique | 去除重复元素 | bincount | 对整数数组的元素计数 |
histogram | 一维直方图统计 |
np.unique()返回去除重复元素后的数组,并按从小到大的顺序排列
np.unique(ndarray, return_index, return_inverse)
return_index:为True时,返回:新数组在原数组中的下标组成的数组,默认为False
return_inverse:为True时,返回:原始数组在新数组中的下标组成的数组,默认为False
- import numpy as np
- np.random.seed(1)
-
- a = np.random.randint(0,10,size = (10,))
- print(a)
-
- r1 = np.unique(a,return_index = True,return_inverse = True)
- print(r1)
'运行
结果如下:
- [5 8 9 5 0 0 1 7 6 9]
- (array([0, 1, 5, 6, 7, 8, 9]), #新数组
- array([4, 6, 0, 8, 7, 1, 2], dtype=int64),
- array([2, 5, 6, 2, 0, 0, 1, 4, 3, 6], dtype=int64))
np.bincount()对整数数组中各个元素的出现次数进行统计,要求原数组必须是非负的
np.bincount(ndarray, weights = )
返回一个数组,数组中下标为i的元素表示:数字i出现的次数
- import numpy as np
- np.random.seed(1)
-
- a = np.random.randint(0,10,size = (10,))
- print(a)
-
- r1 = np.bincount(a)
- print(r1)
'运行
结果如下:
- [5 8 9 5 0 0 1 7 6 9]
- [2 1 0 0 0 2 1 1 1 2]
即:0出现2次,1出现1次,3出现0次……
参数weights可以指定一个数组w,表示每个数所对应的权值。
返回数组a中的每个整数所对应的w中的权值之和,例如:
- import numpy as np
- np.random.seed(1)
-
- a = np.random.randint(0,4,size = (5,))
- print(a)
-
- w = np.array([0.1,0.2,0.3,0.4,0.5])
- print(w)
-
- r1 = np.bincount(a,weights = w)
- print(r1)
'运行
结果如下:
- [1 3 0 0 3]
- [0.1 0.2 0.3 0.4 0.5]
- [0.7 0.1 0. 0.7]
即:0所对应的权值为0.3+0.4=0.7;1所对应的权值为0.1;
2所对应的权值为0;3所对应的权值为0.2+0.5=0.7
所以返回[0.7, 0.1, 0, 0.7]
np.histogram()对一维数组进行直方图统计
np.histogram(ndarray, bis = , range = , weights = , density = )
bis:统计区间的个数,bis是一个数,则将统计范围等分成bis份;若bis是一个数组,则可以实现区间的不等分,例如[0, 0.1, 0.3, 0.4, 0.9, 1]
range:该参数是一个长度为2的元组,表示统计范围的最小值和最大值。默认为None,即(a.min(), a.max())
weights:与np.biscount()中的weights类似,表示权值,若指定weights参数,则对区间中数值所对应的权值进行求和
density:为False时,返回ndarray的数据在每个区间中的个数;True时,返回每个区间的概率密度
该方法返回两个一维数组:hist和bin_edges。hist是每个区间的统计结果,bin_edges是hist所对应的区间,的长度是len(hist)+1,每两个相邻数值构成一个统计区间
例如:
- import numpy as np
- np.random.seed(1)
-
- a = np.random.rand(100)
-
- r1 = np.histogram(a,bins = 5,range = (0,1))
- print(r1)
'运行
结果如下:
- (array([24, 16, 21, 20, 19], dtype=int64),
- array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]))
即:生成100个0~1之间的随机数,然后将区间(0, 1)等分成5份,结果显示有24(第一个数组的结果)个元素在0~0.2(第二个数组的结果)之间,16个元素在0.2~0.4之间……
函数总览
函数名 | 功能 | 函数名 | 功能 |
where | 矢量化判断表达式 | piecewise | 分段函数 |
select | 多分支判断选择 |
x = np.where(condition, y, z)
其中condition, y, z都是数组,其返回值是一个形状与condition相同的数组
当condition中的某个元素为True时,x中对应下标的值从数组y获取,否则从z获取
- import numpy as np
- np.random.seed(1)
-
- x = np.random.randint(0,10,size = (5,))
- print(x)
-
- y = np.where(x<5,'yes','no')
- print(y)
'运行
结果如下:
- [5 8 9 5 0]
- ['no' 'no' 'no' 'no' 'yes']
如果分段函数分段的数量很多,就需要用np.where()一层一层嵌套,不利于编写与阅读用np.select()就可以解决这个问题
select(condlist, choicelist, default = 0)
condlist:长度为N的布尔数组列表(必须是列表形式),用于判断分段的条件(例如x是否<5)
choicelist:长度为N的储存候选值的数组列表(必须是列表形式),用于具体计算
default:当所有条件都不满足时,用default填上
关于布尔数组,例如:
- import numpy as np
- np.random.seed(1)
-
- a = np.random.randint(0,10,size = 5)
- print(a)
- x = [a<5] #布尔数组
- print(x)
'运行
结果如下:
- [5 8 9 5 0]
- [array([False, False, False, False, True])]
对于np.select的具体用法,
例如:分段函数:x<5时,y=x**2;5<=x<=10时,y=-x;x>10时,y=0
- import numpy as np
- np.random.seed(5)
-
- x = np.random.randint(0,15,size = 10)
- print(x)
-
- #指明自变量分段的条件
- condition = [x<5,
- np.logical_and(x>=5,x<=10), #用逻辑运算,Python不支持5<=x<=10
- x>10]
-
- #指明各段的函数
- choice = [x**2,-x,0]
-
- y = np.select(condition,choice)
- print(y)
'运行
结果如下:
- [ 3 14 13 6 6 0 9 8 4 7]
- [ 9 0 0 -6 -6 0 -9 -8 16 -7]
尽管用np.select,如果输入的数组很大,计算时会产生许多保存中间结果的数组,会发生大量内存分配和释放。为了解决这个问题,有np.piecewise()专门计算分段函数
np.piecewise(x, condlist, funclist)
condlist:长度为M的布尔数组列表
funclist:长度为M或M+1的函数列表,这些函数的输入和输出都是数组;如果长度为M,则正常计算;如果长度为M+1,则最后一个函数计算所有条件都为False时的值
例如:分段函数:x<5时,y=x**2;5<=x<=10时,y=-x;x>10时,y=0
- import numpy as np
- np.random.seed(5)
-
- x = np.random.randint(0,15,size = 10)
- print(x)
-
- #指明自变量分段的条件
- condition = [x<5,
- np.logical_and(x>=5,x<=10), #用逻辑运算,Python不支持5<=x<=10
- x>10]
-
- #指明各段的函数,此处需要用lambda
- funclist = [lambda x:x**2,
- lambda x:-x,
- 0]
-
- y = np.piecewise(x,condition,funclist)
- print(y)
'运行
结果如下:
- [ 3 14 13 6 6 0 9 8 4 7]
- [ 9 0 0 -6 -6 0 -9 -8 16 -7]
函数总览
函数名 | 功能 | 函数名 | 功能 |
concatenate | 连接多个数组 | vstack | 沿第0轴连接数组 |
hstack、c_[] | 沿第1轴连接数组 | column_stack | 按列连接多个一维数组 |
split、array_split | 将数组分为多段 | transpose | 重新设置轴的顺序 |
swapaxes | 交换两个轴的顺序 |
用于连接多个数组,第一个参数为需要连接的数组,用()括起来,第二个参数是axis,用于指定沿axis轴进行连接,默认为0
- import numpy as np
- np.random.seed(5)
-
- a = np.zeros((3,3))
- b = np.ones((3,3))
-
- r1 = np.concatenate((a,b))
- print(r1)
-
- r2 = np.concatenate((a,b),axis = 1)
- print(r2)
'运行
结果如下:
- [[0. 0. 0.]
- [0. 0. 0.]
- [0. 0. 0.]
- [1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]]
- [[0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]]
np.vstack()用于沿着第0轴连接数组,当被连接数组是长度为N的一维数组时,将其形状改为(1, N)
其参数为要连接的数组,用()括起来
- import numpy as np
- np.random.seed(5)
-
- a = np.zeros((3,3))
- b = np.ones((3,3))
-
- r1 = np.vstack((a,b))
- print(r1)
'运行
结果如下:
- [[0. 0. 0.]
- [0. 0. 0.]
- [0. 0. 0.]
- [1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]]
与np.vstack()相似,沿着第1轴连接数组,当所有数组都是一维时,沿着第0周连接数组
- import numpy as np
- np.random.seed(5)
-
- a = np.zeros((3,3))
- b = np.ones((3,3))
-
- r1 = np.hstack((a,b))
- print(r1)
'运行
结果如下:
- [[0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]]
和np.hstack()一样,按列连接数组
调用格式为:np.c_[a,b]
- import numpy as np
- np.random.seed(5)
-
- a = np.zeros((3,3))
- b = np.ones((3,3))
-
- r1 = np.c_[a,b]
- print(r1)
'运行
结果如下:
- [[0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]
- [0. 0. 0. 1. 1. 1.]]
np.split()、np.array_split()用法基本相同,将一个数组沿着指定轴分成多个数组,可以直接或指定切分轴上的切分点下标
np.split(a, indices_or_sections, axis=0)
indices_or_sections:类型为int或一维数组,表示切的位置。如果值是一个整数n的话,就将数组平均分为n份(如果不能平均分则报错);如果是一个数组的话,就医数组中的数字为索引切开
axis:对于二维数组,axis = 0表示横向切(用刀横着切数组),axis = 表示纵向切
具体见下方实例:
1.当 indices_or_sections为整数时):
- import numpy as np
- np.random.seed(5)
-
- a = np.arange(1,10).reshape(3,3)
- print(a)
-
- r1 = np.split(a,3) # indices_or_sections为整数
- print(r1)
-
- A,B,C = np.split(a,3) # indices_or_sections为整数
- print(A)
- print(B)
- print(C)
'运行
结果如下:
- [[1 2 3]
- [4 5 6]
- [7 8 9]]
-
- [array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]
-
- [[1 2 3]]
-
- [[4 5 6]]
-
- [[7 8 9]]
2.当 indices_or_sections为数组时(axis = 0):
- import numpy as np
- np.random.seed(5)
-
- a = np.arange(5*6).reshape(5,6)
- print(a)
-
- A,B,C = np.split(a,[1,4])
- print(A)
- print(B)
- 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]
- [24 25 26 27 28 29]]
-
- #横向切(横着切),在纵向下标为1和4处分隔
- [[0 1 2 3 4 5]]
-
- [[ 6 7 8 9 10 11]
- [12 13 14 15 16 17]
- [18 19 20 21 22 23]]
-
- [[24 25 26 27 28 29]]
3.当 indices_or_sections为数组时(axis = 0):
- import numpy as np
- np.random.seed(5)
-
- a = np.arange(5*6).reshape(5,6)
- print(a)
-
- A,B,C = np.split(a,[1,4],axis = 1)
- print(A)
- print(B)
- 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]
- [24 25 26 27 28 29]]
-
- #纵向切(竖着切),在横向下标为1和4处分隔
- [[ 0]
- [ 6]
- [12]
- [18]
- [24]]
-
- [[ 1 2 3]
- [ 7 8 9]
- [13 14 15]
- [19 20 21]
- [25 26 27]]
-
- [[ 4 5]
- [10 11]
- [16 17]
- [22 23]
- [28 29]]
np.transpose()用于修改轴的顺序
例如:np.transpose(a,[1,2,0])表示:新数组的第0轴存放a的第1轴,新数组的第1轴存放a的第2轴,新数组的第2轴存放a的第0轴
- import numpy as np
-
- a = np.arange(1*2*3).reshape(1,2,3)
- print(a.shape)
-
- r1 = np.transpose(a,[1,2,0])
- print(r1.shape)
'运行
结果如下:
- (1, 2, 3)
- (2, 1, 3)
'运行
np.swapaxes()用于交换两个轴的顺序
例如:np.swapaxes(a,0,1)表示:将a的第0轴和第1轴交换顺序
- import numpy as np
-
- a = np.arange(2*3*4).reshape(2,3,4)
- print(a.shape)
-
- r1 = np.swapaxes(a,0,1)
- print(r1.shape)
'运行
结果如下:
- (2, 3, 4)
- (3, 2, 4)
'运行
np.poly1d()可以将列表、数组转化成poly1d对象,该对象可以像函数一样调用
- import numpy as np
-
- a = np.array([1,2,3])
- r1 = np.poly1d(a)
- print(r1)
'运行
结果如下:
- 2
- 1 x + 2 x + 3
即表示:
用法1:可以像函数一样被调用:
- import numpy as np
-
- a = np.array([1,2,3])
- f = np.poly1d(a)
- print(f)
-
- r1 = f(2) #x=2带入
- print(r1)
'运行
结果如下:
- 2
- 1 x + 2 x + 3
-
- 11 #表示x=2时上式的结果
用法2:多项式的四则运算
- import numpy as np
-
- a = np.array([1,2,3])
- f = np.poly1d(a)
- print(f)
-
- print(f + [5,5])
- print(f*2)
- print(f*f)
- print(f/[1,3])
'运行
结果如下:
- 2
- 1 x + 2 x - 3 # f
-
- 2
- 1 x + 7 x + 2 # f + [5,5]
-
- 2
- 2 x + 4 x - 6 # f*2
-
- 4 3 2
- 1 x + 4 x - 2 x - 12 x + 9 # f*f
-
- (poly1d([ 1., -1.]), poly1d([0.])) #f/[1,3]
- #返回两个poly1d类型的元素,第一个是商,第二个是余数
deriv()用于计算多项式函数的微分,调用格式为:poly1d对象.deriv()
- import numpy as np
-
- a = np.array([1,2,-3])
- f = np.poly1d(a)
- print(f)
-
- r1 = f.deriv()
- print(r1)
'运行
结果如下:
- 2
- 1 x + 2 x - 3
-
- 2 x + 2
integ()用于计算多项式函数的积分,调用格式为:poly1d对象.integ()
- import numpy as np
-
- a = np.array([1,2,-3])
- f = np.poly1d(a)
- print(f)
-
- r1 = f.integ()
- print(r1)
'运行
结果如下:
- 2
- 1 x + 2 x - 3
- 3 2
- 0.3333 x + 1 x - 3 x
np.roots()用于计算多项式函数的根,调用格式为:np.roots(poly1d对象)
- import numpy as np
-
- a = np.array([1,2,-3])
- f = np.poly1d(a)
- print(f)
-
- r1 = np.roots(f)
- print(r1)
'运行
结果如下:
- 2
- 1 x + 2 x - 3
- [-3. 1.]
np.poly()可以通过根求多项式系数
- import numpy as np
-
- a = np.array([1,2])
- r1 = np.poly(a)
- print(r1)
'运行
结果如下:
[ 1. -3. 2.]
np.polyfit():根据数据拟合出相应的多项式函数,找出与这组数据的误差平方最小的多项式的系数
np.polyfit(x, y, 最高次的次数)
- import numpy as np
-
- a = np.array([1,2,3,4,5])
- b = np.array([1,4,9,16,25])
-
- r1 = np.polyfit(a,b,3)
- print(r1)
'运行
结果如下:
[ 1.62920807e-17 1.00000000e+00 -4.54973822e-15 2.70557374e-15]
np.polynomial中提供了更丰富的多项式函数类,其中多项式各项的系数按照幂从小到大的顺序排列(与4.7相反)
np.polynomial.Polynomial()可以创建Polynomial对象,并计算多项式函数
- import numpy as np
-
- a = np.array([1,2,3])
- f = np.polynomial.Polynomial(a)
- r1 = f(2) #计算1*(2^0) + 2*(2^1) + 3*(2^2)
- print(r1)
'运行
结果如下:
17.0
'运行
对于Ploynomial对象,p.deriv()可以计算导函数:
- import numpy as np
-
- a = np.array([1,2,3])
- f = np.polynomial.Polynomial(a)
- r1 = f.deriv()
- print(r1)
'运行
结果如下:
poly([2. 6.])
即:,求导得
切比雪夫多项式是一个正交多项式序列,一个n次多项式可以表示为多个切比雪夫多项式的加权和
使用Chebyshev类表示由切比雪夫多项式组成的多项式
多项式可由Chebyshev.basis(i)获得
1.利用convert方法转换多项式类型
语句:Chebyshev.basis(i).convert(kind = )
例如:将转化成Polynomial类:
- import numpy as np
-
- a = np.polynomial.Chebyshev.basis(4)
- print(a)
-
- r1 = a.convert(kind = np.polynomial.Polynomial)
- print(r1)
'运行
结果如下:
- cheb([0. 0. 0. 0. 1.])
- poly([ 1. 0. -8. 0. 8.])
即:
2.切比雪夫节点
切比雪夫多项式的根称为切比雪夫节点可以用于多项式插值。相应的差值多项式能最大程度降低龙格现象(等距插值多项式在两端有很大的振荡),并且提供多项式在连续函数的最佳一致逼近。
详细查看(p101)
函数总览
函数名 | 功能 | 函数名 | 功能 |
dot | 矩阵乘积 | inner | 内积 |
outer | 外积 | tensordot | 张量乘积 |
对于一维数组,其计算内积;对于二维数组,其计算矩阵乘积
通用公式:dot(a, b)[i, j, k, m] = sum(a[i, j, :] * b[k , :, m])
对于一维数组:直接计算内积,即向量点乘
- import numpy as np
- #一维数组
- a = np.arange(3)
- b = np.array([2,3,4])
- print(a)
- print(b)
-
- r1 = np.dot(a,b)
- print(r1)
'运行
结果如下:
- [0 1 2]
- [2 3 4]
- 11 # 0*2 + 1*3 + 2*4
对于二维数组:进行矩阵乘法(第一行乘第一列,m*n与n*k才能相乘)
- import numpy as np
- # 二维数组
- a = np.arange(6).reshape(3,2)
- b = np.array([[2,3,4],[5,6,7]])
- print(a)
- print(b)
-
- r1 = np.dot(a,b)
- print(r1)
'运行
结果如下:
- [[0 1]
- [2 3]
- [4 5]]
-
- [[2 3 4]
- [5 6 7]]
-
- [[ 5 6 7]
- [19 24 29]
- [33 42 51]]
np.inner()用于计算内积
对于一维数组,inner()和dot()一样,
对于二维数组,具体计算过程见下例
计算内积时,需保证两个矩阵形状相同!!!
- import numpy as np
- # 二维数组
- a = np.arange(6).reshape(2,3)
- b = np.array([[2,3,4],[5,6,7]])
- print(a)
- print(b)
-
- r1 = np.inner(a,b)
- print(r1)
'运行
结果如下:
- [[0 1 2] # a行
- [3 4 5]] # b行
-
- [[2 3 4] # c行
- [5 6 7]] # d行
-
- [[11 20] # [a*c a*d]
- [38 74]] # [b*c b*d]
np,outer()用于计算外积,且只对一维数组进行计算,如果传入的是多维数组,先将数组展平为一维数组再计算(具体计算过程见下例)
对于一维数组:
- import numpy as np
- # 一维数组
- a = np.arange(3)
- b = np.array([2,3,4])
- print(a)
- print(b)
-
- r1 = np.outer(a,b)
- print(r1)
'运行
结果如下:
- [0 1 2]
-
- [2 3 4]
-
- [[0 0 0] # [0*2 0*3 0*4] 或 [a11*b11 a11*b12 a11*b13]
- [2 3 4] # [1*2 1*3 1*4]
- [4 6 8]] # [2*2 2*3 2*4]
对于二维数组:
- import numpy as np
- # 二维数组
- a = np.arange(6).reshape(2,3)
- b = np.array([[2,3,4],[5,6,7]])
- print(a)
- print(b)
-
- r1 = np.outer(a,b)
- print(r1)
'运行
结果如下:
- [[0 1 2]
- [3 4 5]]
- [[2 3 4]
- [5 6 7]]
- [[ 0 0 0 0 0 0] # [0*2 0*3 0*4 0*5 0*6 0*7]
- [ 2 3 4 5 6 7] # [1*2 1*3 1*4 1*5 1*6 1*7]
- [ 4 6 8 10 12 14] # ……
- [ 6 9 12 15 18 21]
- [ 8 12 16 20 24 28]
- [10 15 20 25 30 35]]
np.tensordot()将两个多维数组a和b指定轴上的对应元素相乘并求和
np.tensordot(a,b,axes = [[轴1],[轴2]])
axes有两个参数,第一个表示a中的轴,第二个表示b中的轴,该方法会将指定轴的对应元素相乘再相加
(即:第一?和第一?相乘并相加,放在a11,第一?和第二?相乘再相加,放在a12,……其中轴1和轴2分别控制两个问号,0表示列,1表示行。例如:axes = [[0],[1]]表示第一列和第一行相乘并相加,放在a11,以此类推……)
如果axes是整数,则表示把a中的后axes个轴和b中的前axes个轴进行相乘再相加的运算,其他轴保持不变
- import numpy as np
- # 二维数组
- a = np.arange(9).reshape(3,3)
- b = np.array([[2,3,4],[5,6,7],[8,9,10]])
- print(a)
- print(b)
-
- r1 = np.tensordot(a,b,axes = [[0],[0]]) #表示a的列和b的列相乘,放在a11……
- print(r1)
'运行
结果如下:
- [[0 1 2]
- [3 4 5]
- [6 7 8]]
-
- [[ 2 3 4]
- [ 5 6 7]
- [ 8 9 10]]
-
- [[ 63 72 81]
- [ 78 90 102]
- [ 93 108 123]]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。