当前位置:   article > 正文

Python NumPy库 常见基本用法总结(学习笔记)_python np

python np

目录

简介

1.ndarray对象

1.1 创建数组

1.1.1 np.array()

1.2 数组形状与元素类型

1.2.1 ndarray.shape  #获得形状

1.2.2 ndarray.reshape()  #改变形状

1.2.3 ndarray.dtype  #获得元素类型

1.2.4 ndarray.astype()  #转换元素类型

 1.2.5 np.set_printoptions(precision = )  #控制小数点位数

1.3 自动生成数组

1.3.1 np.arange()  #等差一维数组

1.3.2 np.linspace()  #等差一维数组

1.3.3 np.logspace()  #指数数组

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 存取元素

1.4.1 下标、切片

1.4.2 ndarray[[ ]]  #批量提取数组元素

1.4.3 ndarray.take()  #获取元素

1.4.3 np.compress()  #通过布尔数组获取元素

1.5 多维数组

1.5.1 二维数组的创建

1.5.2 二维数组的切片

1.6 结构数组

1.6.1 定义结构数组 np.dtype()

1.6.2 结构数组的存取

2.ufunc对象

2.1 四则运算

2.2 比较运算和布尔运算

2.2.1 比较运算(<,=,>)

2.2.2 布尔运算(np.logical_and、or、not)

2.2.3 布尔运算(np.all()、np.any())

2.3 自定义ufunc函数

2.3.1 np.frompyfunc()  #分段函数

2.4 广播(broadcasting)

2.4.1 广播处理规则

2.4.2 np.broadcast_arrays()  #查看广播之后的数组

2.4.3 ndarray.repeat()  #复制元素

2.4.4 下标对象None

2.5 ufunc的方法

2.5.1 np..reduce()  #对数组内元素四则运算

2.5.2 np..accumulate()  #对数组内元素四则运算

2.5.3 np..reduceat()  计算多组reduce()的结果

2.5.4 np..outer()  #计算表

3.多维数组的下标存取

3.1 下标对象

3.2 整数数组作为下标

3.3 布尔数组作为下标

3.3.1 np.nonzero()  #找出不为0的元素

4.NumPy的函数库

4.1 随机数(np.random模块)

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.1.10 np.random.seed()  #种子

4.2 求和、平均值、方差

4.2.1 np.sum()  #求和

4.2.2 np.mean()  #求平均数

4.2.3 np.average()  #计算加权平均数

4.2.4 np.std()  #计算标准差

4.2.5 np.var()  #计算方差

4.2.6 np.product()  #计算所有元素乘积

4.3 大小与排序

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.4 np.sort()  #排序

4.3.5 np.argsort()  #排序后的下标

4.3.6 np.lexsort()  #多列排序

4.3.6 np.lexsort() 应用:成绩姓名全局排序

4.3.7 np.partition(),np.argpartition()  #数组分割

4.3.8 np.median()  #计算中位数

4.3.9 np.percentile()  #计算百分数

4.3.10 np.searchsorted()  #插入元素(二分查找)

4.4 统计函数

4.4.1 np.unique()  #去除重复元素

4.4.2 np.bincount()  #对整数数组的元素计数

4.4.3 np.histogram()  #直方图统计

4.5 分段函数

4.5.1 np.where()  #if

4.5.2 np.select()  #多分支的if

4.5.3 np.piecewise()  #分段函数

4.6 操作多维数组

4.6.1 np.concatenate()  #连接多个数组

4.6.2 np.vstack()  #沿第0轴连接数组

4.6.3 np.hstack()  #沿第1轴连接数组

4.6.4 np.c[]  #按列连接多个一维数组

4.6.5 np.split()、np.array_split()  #将数组分为多段

4.6.6 np.transpose()、np.swapaxes()  #重新设置轴的顺序

4.6.7 np.swapaxes()  #交换两个轴的顺序

4.7 多项式函数

4.7.1 np.poly1d()  #转化成poly1d对象

4.7.2 deriv()  #计算微分

4.7.3 integ()  #计算积分

4.7.4 np.roots()  #求根

4.7.5 np.poly()  #用根求多项式方程

4.7.6 np.polyfit()  #拟合多项式函数

4.8 多项式函数类

4.8.1 np.polynomial.Polynomial()  #创建Polynomial对象

4.8.2 p.deriv()  #计算导函数

4.8.3 np.polynomial.Chebyshev()(拓展)

4.9 各种乘积运算

4.9.1 np.dot()  #矩阵乘积

4.9.2 np.inner()  #内积

4.9.3 np.outer()  #外积

4.9.4 np.tensordot()  #张量乘积


简介

NumPy提供了两种基本的对象:

1.ndarry:储存单一数据类型的多维数组

2.nfunc:对数组进行处理的特殊函数

查看numpy库的版本:

  1. import numpy
  2. print(numpy.__version__)
'
运行

结果如下:

1.19.2

1.ndarray对象

1.1 创建数组

1.1.1 np.array()

用np.array()创建数组,括号中可以是列表、元组、多维列表:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = np.array((1,2,3))
  4. c = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
  5. print(a)
  6. print(b)
  7. print(c)
'
运行

结果如下:

  1. [1 2 3]
  2. [1 2 3]
  3. [[ 1 2 3 4]
  4. [ 5 6 7 8]
  5. [ 9 10 11 12]]

1.2 数组形状与元素类型

1.2.1 ndarray.shape  #获得形状

用ndarray.shape可获得数组的形状,返回元组(几行,几列):

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
  4. print(a.shape)
  5. print(b.shape)
'
运行

结果如下:

  1. (3,)
  2. (3, 4)
'
运行

1.2.2 ndarray.reshape()  #改变形状

用ndarray.reshape(x,y)可以改变数组形状:

  1. import numpy as np
  2. a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
  3. print(a)
  4. b = a.reshape(2,6)
  5. print(b)
'
运行

结果如下:

  1. [[ 1 2 3 4]
  2. [ 5 6 7 8]
  3. [ 9 10 11 12]]
  4. [[ 1 2 3 4 5 6]
  5. [ 7 8 9 10 11 12]]

(ps.b是通过a的转化得来,因此在这之后对a操作也会引起b的变化,示例如下:)

  1. import numpy as np
  2. a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
  3. b = a.reshape(2,6)
  4. a[0][0] = 100
  5. print(a)
  6. print(b)
'
运行

结果如下:

  1. [[100 2 3 4]
  2. [ 5 6 7 8]
  3. [ 9 10 11 12]]
  4. [[100 2 3 4 5 6]
  5. [ 7 8 9 10 11 12]]

1.2.3 ndarray.dtype  #获得元素类型

ndarray.dtype可以得到数组元素的类型:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. print(a.dtype)
'
运行

结果如下:

int32

即32位的长整型(默认值与操作系统和Python有关)

1.2.4 ndarray.astype()  #转换元素类型

astype()方法可以对数组的元素类型进行转换:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = a.astype(np.float)
  4. c = a.astype(np.complex)
  5. print(b.dtype)
  6. print(b)
  7. print(c.dtype)
  8. print(c)

结果如下:

  1. float64
  2. [1. 2. 3.]
  3. complex128
  4. [1.+0.j 2.+0.j 3.+0.j]

 1.2.5 np.set_printoptions(precision = )  #控制小数点位数

该函数可以控制输出的数组中显示小数点位数

(set_printoptions()里还有很多参数,在此仅说明precision的意义)

  1. import numpy as np
  2. np.set_printoptions(precision = 3) #四舍五入保留三位小数
  3. a = np.array([0.12345,2.54687])
  4. print(a)
'
运行

结果如下:

[0.123 2.547]

1.3 自动生成数组

1.3.1 np.arange()  #等差一维数组

np.arange(start, stop, step)可以创建等差数列的一维数组,其中开始值和终值遵循“左闭右开”的原则,类似于list中的range()

  1. import numpy as np
  2. a = np.arange(0,1,0.1)
  3. print(a)
'
运行

结果如下:

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]

1.3.2 np.linspace()  #等差一维数组

np.linspace(start, stop, number, endpoint = )中可以指定开始值、终值和元素个数,可以通过endpoint参数指定是否包含终值,endpoint = True 则包含终值(默认为True)

  1. import numpy as np
  2. a = np.linspace(0,1,10,endpoint = False)
  3. print(a)
'
运行

结果如下:

[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]

1.3.3 np.logspace()  #指数数组

np.logspace()与np.linspace()相似,其start和stop为10的幂,例如(0,3,3)表示从10^{0}开始到10^{3},元素数量为4的等比数列:

  1. import numpy as np
  2. a = np.logspace(0,3,4)
  3. print(a)
'
运行

结果如下:

[   1.   10.  100. 1000.]

1.3.4 np.zeros()、np.ones()、np.empty()、np.full()  #特殊数组

np.zeros():创建制定形状的全零数组

np.ones():创建制定形状的全一数组

np.empty():只分配数组所使用的内存

np.full():将元素初始化为指定的值

  1. import numpy as np
  2. a = np.zeros((2,3),int)
  3. b = np.ones((2,3),int)
  4. c = np.empty((2,3),float)
  5. d = np.full((2,3),666)
  6. print(a)
  7. print(b)
  8. print(c)
  9. print(d)
'
运行

结果如下:

  1. [[0 0 0]
  2. [0 0 0]]
  3. [[1 1 1]
  4. [1 1 1]]
  5. [[1. 1.1 1.2]
  6. [9.7 9.8 9.9]]
  7. [[666 666 666]
  8. [666 666 666]]

1.3.5 np.zeros_like()、np.ones_like()、np.empty_like()、np.full_like()  #形状相同的特殊数组

括号中输入数组,创建与输入数组相同形状的全零数组、全一数组等等

以np.zeros_like()为例:

  1. import numpy as np
  2. a = [[1,2,3,4],[5,6,7,8]]
  3. print(a)
  4. b = np.zeros_like(a)
  5. print(b)
'
运行

结果如下:

  1. [[1, 2, 3, 4], [5, 6, 7, 8]]
  2. [[0 0 0 0]
  3. [0 0 0 0]]

1.4 存取元素

1.4.1 下标、切片

与列表(list)中操作相同,不再赘述

1.4.2 ndarray[[ ]]  #批量提取数组元素

两个[[ ]]中填入需要的元素下标,该操作可以提取ndarry指定下标的元素并组成一个新的数组:

  1. import numpy as np
  2. a = np.arange(10,20,1)
  3. print(a)
  4. b = a[[2,4,6,8]]
  5. print(b)
'
运行

结果如下:

  1. [10 11 12 13 14 15 16 17 18 19]
  2. [12 14 16 18]

这种方法中,可以理解为:b是将a中元素提取后重新创建的一个数组,因此a和b不共用内存,所以对a操作不会影响b,a和b是相互独立的,互不影响。

ndarray[[ ]]也可以快速修改指定下标位置处元素的值:

  1. import numpy as np
  2. a = np.arange(0,10,1)
  3. print(a)
  4. a[[2,4,6,8]] = 0,0,0,0
  5. print(a)
'
运行

结果如下:

  1. [0 1 2 3 4 5 6 7 8 9]
  2. [0 1 0 3 0 5 0 7 0 9]

1.4.3 ndarray.take()  #获取元素

沿着指定轴获取元素

  1. import numpy as np
  2. a = np.arange(3*4).reshape(3,4)
  3. print(a)
  4. result = a.take(indices = 0,axis = 1)
  5. print(result)
'
运行

结果如下:

  1. [[ 0 1 2 3]
  2. [ 4 5 6 7]
  3. [ 8 9 10 11]]
  4. [0 4 8]

即:沿着axis = 1(纵轴)取第0列元素

1.4.3 np.compress()  #通过布尔数组获取元素

沿着指定轴通过布尔数组获取元素

np.compress(condition, ndarray, axis = )

  1. import numpy as np
  2. a = np.array([0,1,-2,0,3])
  3. print(a)
  4. b = np.compress([1,0,1],a,axis = 0)
  5. print(b)
  6. c = np.compress([1,0,1,0,1],a,axis = 0)
  7. print(c)
'
运行

结果如下:

  1. [ 0 1 -2 0 3]
  2. [ 0 -2]
  3. [ 0 -2 3]

即在数组a中,沿着axis = 0的轴(横轴),取布尔数组中真值对应下标的元素

1.5 多维数组

1.5.1 二维数组的创建

二维数组的创建实际上是一个加法表,由纵向量和横向量的元素相加而得,例如:

  1. import numpy as np
  2. a = np.arange(0,60,10).reshape(-1,1)
  3. b = np.arange(0,6)
  4. print(a)
  5. print(b)
  6. print(a+b)
'
运行

结果如下:

  1. [[ 0]
  2. [10]
  3. [20]
  4. [30]
  5. [40]
  6. [50]]
  7. [0 1 2 3 4 5]
  8. [[ 0 1 2 3 4 5]
  9. [10 11 12 13 14 15]
  10. [20 21 22 23 24 25]
  11. [30 31 32 33 34 35]
  12. [40 41 42 43 44 45]
  13. [50 51 52 53 54 55]]

1.5.2 二维数组的切片

  1. import numpy as np
  2. a = np.arange(0,60,10).reshape(-1,1) + np.arange(0,6)
  3. print(a)
  4. print('\n')
  5. print(a[0,3:5]) #表示第0行的第3到5个元素
  6. print('\n')
  7. print(a[4:,4:]) #第4行之后及第4列之后元素组成的数组
  8. print('\n')
  9. print(a[:,2]) #每一行的第二个元素组成的列表
  10. print('\n')
  11. print(a[2::2,::2])
'
运行

结果如下:

  1. [[ 0 1 2 3 4 5]
  2. [10 11 12 13 14 15]
  3. [20 21 22 23 24 25]
  4. [30 31 32 33 34 35]
  5. [40 41 42 43 44 45]
  6. [50 51 52 53 54 55]]
  7. [3 4]
  8. [[44 45]
  9. [54 55]]
  10. [ 2 12 22 32 42 52]
  11. [[20 22 24]
  12. [40 42 44]]

需要注意的是,b = a[0,3:5]这样的切片中,b是a的视图,他们共享数据,因此,改变a会对b造成影响

1.6 结构数组

1.6.1 定义结构数组 np.dtype()

创建一个dtype对象person,其参数是字典,键:'names','formats',

其中names定义结构中每个字段的名称;formats定义每个字段的类型:

        'S30':长度为30个字节的字符串类型,(必须指明其长度)

        'i':32位的整数类型,相当于'np.int32'

        'f':32位的单精度浮点型,相当于'np.float32'

然后调用array()创建数组,通过dtype参数来制定创建的数组的元素类型为person

  1. import numpy as np
  2. person = np.dtype({
  3. 'names':['name','age','height'], #'names'是固定名称,不可更改,但name、age等可更改
  4. 'formats':['S30','i','f']}, #'formats'是固定名称,不可更改
  5. align = True)
  6. a = np.array([('Jia',20,177),('Zhang',19,159)],dtype = person)
  7. print(a)
  8. print(a.dtype)
'
运行

结果如下:

  1. [(b'Jia', 20, 177.) (b'Zhang', 19, 159.)]
  2. {'names':['name','age','height'], 'formats':['S30','<i4','<f4'],
  3. 'offsets':[0,32,36], 'itemsize':40, 'aligned':True}

其中'<i4','<f4'的'<'表示低位字节在前,即小端模式(little endian);'>'表示高位字节在前,即大端模式(big endian);不显示则表示忽略字节顺序。

1.6.2 结构数组的存取

结构数组的存取和一般数组相同,通过下标就能获取:

  1. import numpy as np
  2. person = np.dtype({
  3. 'names':['name','age','height'],
  4. 'formats':['S30','i','f']},
  5. align = True)
  6. a = np.array([('Jia',20,177),('Zhang',19,159)],dtype = person)
  7. print(a[0])
'
运行

结果如下:

(b'Jia', 20, 177.)'
运行

需要注意的是,输出的结果长得像元组,但并不是元组,而是结构:

print(a[0].dtype)

结果如下:

  1. {'names':['name','age','height'], 'formats':['S30','<i4','<f4'],
  2. 'offsets':[0,32,36], 'itemsize':40, 'aligned':True}
'
运行

因此可以用字段名作为下标获取相应元素,也可以通过这种方法修改元素:

print(a[0]['name'])

结果如下:

b'Jia''
运行

2.ufunc对象

2.1 四则运算

数组的运算符以及对应的ufunc函数
表达式对应的ufunc函数
y = x1 + x2add(x1, x2 [ ,y])
y = x1 - x2subtract(x1, x2 [ ,y])
y = x1 * x2multiply(x1, x2 [ ,y])
y = x1 / x2divide(x1, x2 [ ,y]),如果两个数组的元素为整数,则用整数除法
y = x1 / x2true_divide(x1, x2 [ ,y]),总是返回精确的商
y = x1 // x2floor_divide(x1, x2 [ ,y]),总是对返回值取整
y = -xnegative(x [ ,y])
y = x1 ** x2power(x1, x2 [ ,y])
y = x1 % x2remainder(x1, x2 [ ,y]),mod(x1, x2 [ ,y])

用符号也可以直接运算:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = np.array([3,2,1])
  4. print(a+b)
  5. print(a-b)
  6. print(a*b)
  7. print(a/b)
  8. print(a//b)
  9. print(-a)
  10. print(a**b)
  11. print(a%b)
'
运行

结果如下:

  1. [4 4 4]
  2. [-2 0 2]
  3. [3 4 3]
  4. [0.33333333 1. 3. ]
  5. [0 1 3]
  6. [-1 -2 -3]
  7. [1 4 3]
  8. [1 0 0]

2.2 比较运算和布尔运算

2.2.1 比较运算(<,=,>)

比较两个数组的对应元素,如果满足要求则不二数组对应位置为True,否则为False

表达式对应的ufunc函数
x1 == x2equal(x1, x2 [ ,y])
x1 !=  x2not_equal(x1, x2 [ ,y])
x1 < x2less(x1, x2 [ ,y])
x1 <= x2less_equal(x1, x2 [ ,y])
x1 > x2greater(x1, x2 [ ,y])
x1 >= x2greater_equal(x1, x2 [ ,y])

用符号也可以直接运算:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = np.array([3,2,1])
  4. print(a == b)
  5. print(a != b)
  6. print(a < b)
  7. print(a <= b)
  8. print(a > b)
  9. print(a >= b)
'
运行

结果如下:

  1. [False True False]
  2. [ True False True]
  3. [ True False False]
  4. [ True True False]
  5. [False False True]
  6. [False True True]

2.2.2 布尔运算(np.logical_and、or、not)

Python中布尔运算使用and、or、not关键字,无法被重载,因此数组的布尔运算只能通过相应的ufunc函数进行,他们都以“logical_”开头:logical_and()、logical_or()、logical_not()

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. b = np.array([3,2,1])
  4. print(np.logical_and(a > b,a == b))
'
运行

结果如下:

[False False False]

2.2.3 布尔运算(np.all()、np.any())

NumPy中也定义了np.any()和np.all()

np.any():只要有一个元素为True就返回True

np.all():只有当全部元素都为True才返回True

  1. import numpy as np
  2. a = np.array([0,1,2,3])
  3. print(np.all(a))
  4. print(np.any(a))
'
运行

结果如下:

  1. False
  2. True
'
运行

2.3 自定义ufunc函数

2.3.1 np.frompyfunc()  #分段函数

通常情况下,自定义(def)出的函数只能计算单个值

例如:定义一个分段函数,小于-10时输出-1,在-10到10之间输出0,大于10输出1。

  1. def f(a,b,x):
  2. if x <= a:
  3. return -1
  4. if a < x <b:
  5. return 0
  6. if x >= b:
  7. return 1
  8. c = 6
  9. result = f(-10,10,c)
  10. 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

  1. import numpy as np
  2. def f(a,b,x):
  3. if x <= a:
  4. return -1
  5. if a < x <b:
  6. return 0
  7. if x >= b:
  8. return 1
  9. function = np.frompyfunc(f,3,1) #只起到转换函数的作用
  10. c = np.arange(-15,15,3)
  11. result = function(-10,10,c) #计算时重新调用function()函数
  12. print(c) #自变量
  13. print(result) #分段函数输出的结果
'
运行

结果如下:

  1. [-15 -12 -9 -6 -3 0 3 6 9 12]
  2. [-1 -1 0 0 0 0 0 0 0 1]

2.4 广播(broadcasting)

使用ufunc函数对两个数组计算时,会对两个数组的对应元素进行计算,因此要求两个数组形状相同。如果不同,会进行广播(broadcasting)处理

2.4.1 广播处理规则

①以维数最多的数组为准,其他数组向它看齐,shape属性中不足的部分通过在前面加1补齐;

②输出数组的shape属性是输入数组shape属性的各个轴上的最大值;

③如果输入数组的某个长度为1,或与输出数组的对应轴长度相同,则这个数组可以用来计算,否则出错;

④当输入数组的某个轴长度为1时,沿着该轴运算时,都用该轴上的第一组值。

具体实例:

先创建一个二维数组a,形状为(6, 1)

  1. import numpy as np
  2. a = np.arange(0,60,10).reshape(-1,1)
  3. print(a)
  4. print(a.shape)
'
运行

结果如下:

  1. [[ 0]
  2. [10]
  3. [20]
  4. [30]
  5. [40]
  6. [50]]
  7. (6, 1)

再创建一维数组b,其形状为(5, ):

  1. import numpy as np
  2. a = np.arange(0,60,10).reshape(-1,1)
  3. b = np.arange(0,5)
  4. print(b)
'
运行

结果如下:

[0 1 2 3 4]

计算a与b的和,得到一个加法表,相当于计算两个数组中所有元素对的和,得到一个形状为(6, 5)的数组:

  1. import numpy as np
  2. a = np.arange(0,60,10).reshape(-1,1)
  3. b = np.arange(0,5)
  4. c = a+b
  5. print(c)
'
运行

结果如下:

  1. [[ 0 1 2 3 4]
  2. [10 11 12 13 14]
  3. [20 21 22 23 24]
  4. [30 31 32 33 34]
  5. [40 41 42 43 44]
  6. [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才能相加,即:

  1. [[0 1 2 3 4]
  2. [0 1 2 3 4]
  3. [0 1 2 3 4]
  4. [0 1 2 3 4]
  5. [0 1 2 3 4]
  6. [0 1 2 3 4]]

对a同理,则可以保证形状相同,才能相加。

2.4.2 np.broadcast_arrays()  #查看广播之后的数组

np.broadcast_arrays()可以查看广播之后的数组,返回广播后的多个数组

  1. import numpy as np
  2. a = np.arange(2*3).reshape(2,3)
  3. print(a)
  4. print(a.shape)
  5. b = np.array([1,2,3])
  6. print(b)
  7. print(b.shape)
  8. result = np.broadcast_arrays(a,b)
  9. print(result)
'
运行

结果如下:

  1. [[0 1 2]
  2. [3 4 5]]
  3. (2, 3)
  4. [1 2 3]
  5. (3,)
  6. [array([[0, 1, 2],
  7. [3, 4, 5]]),
  8. array([[1, 2, 3],
  9. [1, 2, 3]])]

2.4.3 ndarray.repeat()  #复制元素

ndarray.repeat(复制的次数,axis = )

其中,axis = 0表示第0轴(列),即沿着axis = 0的轴,复制数组中各个元素的值

axis = 1表示第1轴(行),同理。

例1:对二维数组,沿第0轴复制

  1. import numpy as np
  2. a = np.array([[1,2,3,4,5]])
  3. print(a)
  4. c = a.repeat(3,axis = 0)
  5. print(c)
'
运行

结果如下:

  1. [[1 2 3 4 5]]
  2. [[1 2 3 4 5]
  3. [1 2 3 4 5]
  4. [1 2 3 4 5]]

例2:对一维数组,沿第0轴复制

  1. import numpy as np
  2. a = np.array([1,2,3,4,5])
  3. print(a)
  4. c = a.repeat(3,axis = 0)
  5. print(c)
'
运行

结果如下:

  1. [1 2 3 4 5]
  2. [1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]

例3:对二维数组,沿第1轴复制

  1. import numpy as np
  2. a = np.array([[1,2,3,4,5]])
  3. print(a)
  4. c = a.repeat(3,axis = 1)
  5. print(c)
'
运行

结果如下:

  1. [[1 2 3 4 5]]
  2. [[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5]]

2.4.4 下标对象None

表示在None对应的位置创建一个长度为1的新轴,例如:a[None, :]和a.reshape(1, -1)等效

  1. import numpy as np
  2. a = np.array([1,2,3,4,5])
  3. print(a)
  4. print(a[None,:])
  5. print(a.reshape(1,-1))
  6. print(a[:,None])
'
运行

结果如下:

  1. [1 2 3 4 5]
  2. [[1 2 3 4 5]]
  3. [[1 2 3 4 5]]
  4. [[1]
  5. [2]
  6. [3]
  7. [4]
  8. [5]]

2.5 ufunc的方法

ufunc方法本身还有一些函数,这些方法只对2个输入、1个输出的ufunc函数有效,其他的ufunc对象调用这些方法时会抛出ValueError异常

2.5.1 np.<op>.reduce()  #对数组内元素四则运算

np.<op>.reduce(array, axis = , dtype = )

<op>是指运算符,例如add、subtract、multiple、divide等等,该方法沿着axis指定的轴对数组进行操作,相当于沿着axis轴,将<op>添加到数组的各个元素之间,输出计算结果,例如:

  1. import numpy as np
  2. a = np.array([1,2,3,4])
  3. b = np.add.reduce(a,axis=0) #1+2+3+4
  4. print(b)
  5. c = np.subtract.reduce(a,axis=0) #1-2-3-4
  6. print(c)
  7. d = np.multiply.reduce(a,axis=0) #1*2*3*4
  8. print(d)
'
运行

结果如下:

  1. 10
  2. -8
  3. 24
'
运行

2.5.2 np.<op>.accumulate()  #对数组内元素四则运算

accumulate与reduce类似,只是返回与输入形状相同的数组,保存所有的中间计算过程:

  1. import numpy as np
  2. a = np.array([1,2,3,4])
  3. b = np.add.accumulate(a,axis=0)
  4. print(b) #[1,1+2,1+2+3,1+2+3+4]
  5. c = np.subtract.accumulate(a,axis=0)
  6. print(c) #[1,1-2,1-2-3,1-2-3-4]
  7. d = np.multiply.accumulate(a,axis=0)
  8. print(d) #[1,1*2,1*2*3,1*2*3*4]
'
运行

结果如下:

  1. [ 1 3 6 10]
  2. [ 1 -1 -4 -8]
  3. [ 1 2 6 24]

2.5.3 np.<op>.reduceat()  计算多组reduce()的结果

reduceat()方法计算多组reduce()的结果,通过indices参数指定一系列的起始和终止位置,例如:

  1. import numpy as np
  2. a = np.array([1,2,3,4])
  3. result = np.add.reduceat(a,indices = [0,1,0,2,0,3,0])
  4. print(result)
'
运行

结果如下:

[ 1  2  3  3  6  4 10]

对于indices的每一个值,都会计算出一个值,结果中除了最后一个参数外,计算过程如下:

  1. if indices[i] < indices[i+1]: #如果该元素小于后面一个元素
  2. result[i] = <op>.reduce(a[indices[i]:indices[i+1]])
  3. else: #如果该元素不小于后面一个元素
  4. result[i] = a[indices[i]]

对于最后一个元素,计算过程如下:

<op>.reduce(a[indices[-1]:])

2.5.4 np.<op>.outer()  #计算表

np.<op>.outer(a,b),其结果是一个计算表(加法表,乘法表,减法表),例如:

  1. import numpy as np
  2. a = np.array([1,2,3,4,5])
  3. b = np.array([2,3,4])
  4. result = np.multiply.outer(a,b)
  5. print(result)
'
运行

结果如下:

  1. [[ 2 3 4]
  2. [ 4 6 8]
  3. [ 6 9 12]
  4. [ 8 12 16]
  5. [10 15 20]]

相当于是乘法表(加法,减法同理):

  1. 2 3 4
  2. ----------
  3. 1| 2 3 4
  4. 2| 4 6 8
  5. 3| 6 9 12
  6. 4| 8 12 16
  7. 5| 10 15 20

3.多维数组的下标存取

3.1 下标对象

多维数组的下标是一个“ 长度 = 数组维度 ”的数组,

如果下标的长度 > 数组维数,则会出错;

如果下标长度 < 数组维数,则会在下标元组后面补“ : ”,使得长度和维数相同。

----------------------------------------------------------------------

如果下标对象不是元组,NumPy会先把他转化成元组,但这个过程可能与用户想的有出入,例如:a是一个三维数组,分别用 二维列表 和 二维数组 作为下标,输出是不一样的: 

  1. import numpy as np
  2. a = np.arange(3*4*5).reshape(3,4,5)
  3. print(a) #三维数组
  4. b = tuple([[0],[1]]) #二维元组
  5. c = np.array([[0],[1]]) #二维数组
  6. print(a[b])
  7. print(a[c])
'
运行

结果如下:

  1. [[[ 0 1 2 3 4]
  2. [ 5 6 7 8 9]
  3. [10 11 12 13 14]
  4. [15 16 17 18 19]]
  5. [[20 21 22 23 24]
  6. [25 26 27 28 29]
  7. [30 31 32 33 34]
  8. [35 36 37 38 39]]
  9. [[40 41 42 43 44]
  10. [45 46 47 48 49]
  11. [50 51 52 53 54]
  12. [55 56 57 58 59]]]
  13. [[5 6 7 8 9]]
  14. [[[[ 0 1 2 3 4]
  15. [ 5 6 7 8 9]
  16. [10 11 12 13 14]
  17. [15 16 17 18 19]]]
  18. [[[20 21 22 23 24]
  19. [25 26 27 28 29]
  20. [30 31 32 33 34]
  21. [35 36 37 38 39]]]]

3.2 整数数组作为下标

如果下标元组的所有元素都是切片和整数,那么用它作为下标的得到的是原始数组的一个视图,即它和原始数组共享数据空间

3.3 布尔数组作为下标

布尔数组作为下标对象时,相当于用nonzero()将布尔数组转化成一组整数数组,然后用整数数组进行下标运算

3.3.1 np.nonzero()  #找出不为0的元素

np.nonzero()返回数组中元素不为零的值的下标组成的数组,例如:

  1. import numpy as np
  2. a = np.array([0,1,-2,0,3])
  3. print(a)
  4. b = np.nonzero(a)
  5. print(b)
'
运行

结果如下:

  1. [ 0 1 -2 0 3]
  2. (array([1, 2, 4], dtype=int64),)

4.NumPy的函数库

4.1 随机数(np.random模块)

笔记函数总览:

函数名功能函数名功能
rand0到1之间的随机数randn标准正态分布的随机数
randint指定范围内的随机整数normal正态分布
uniform均匀分布poisson泊松分布
permutation随机排列shuffle随机打乱顺序
choice随机抽取样本seed设置随机数种子

4.1.1 np.random.rand()(产生随机0~1浮点数)

产生0到1之间的随机浮点数,所有参数用于指定所产生数组的形状

  1. import numpy as np
  2. a = np.random.rand()
  3. print(a)
  4. b = np.random.rand(2,3)
  5. print(b)
'
运行

结果如下:

  1. 0.26454873391353306
  2. [[0.32604263 0.61228564 0.92722863]
  3. [0.3631769 0.53571405 0.04554973]]

4.1.2 np.random.randn()(产生正态分布随机数)

产生服从标准正态分布的随机数,参数含义与rand()相同

  1. import numpy as np
  2. a = np.random.randn()
  3. print(a)
  4. b = np.random.randn(2,3)
  5. print(b)
'
运行

结果如下:

  1. -0.07751610157473836
  2. [[ 0.20687204 0.41934397 -0.80796835]
  3. [ 0.44276644 0.84450041 -0.41650222]]

4.1.3 np.random.randint()(产生随机整数)

产生指定范围内的随机整数,范围左闭右开

np.random.randint(start, stop, shape)

参数分别指定:起始值,终值,产生数组的形状(若没有这一项则默认返回一个随机整数)

  1. import numpy as np
  2. b = np.random.randint(0,10)
  3. print(b)
  4. c = np.random.randint(0,10,(2,3))
  5. print(c)
'
运行

结果如下:

  1. 3
  2. [[5 8 9]
  3. [5 2 3]]

4.1.4 np.random.normal()(随正态分布)

正态分布,其参数有三个,分别是:期望值、标准差、形状。例如:

  1. import numpy as np
  2. a = np.random.normal(100,10)
  3. print(a)
  4. b = np.random.normal(100,10,(2,3))
  5. print(b)
'
运行

 结果如下:

  1. 97.37335368991738
  2. [[ 99.207 88.422 113.329]
  3. [100.994 81.526 99.495]]

4.1.5 np.random.uniform()(均匀分布)

均匀分布,其参数有三个,分别是:起始值、终值、形状。例如:

  1. import numpy as np
  2. a = np.random.uniform(10,20)
  3. print(a)
  4. b = np.random.uniform(10,20,(2,3))
  5. print(b)
'
运行

结果如下:

  1. 17.06049626065125
  2. [[16.817 16.852 14.206]
  3. [13.688 15.58 18.359]]

4.1.6 np.random.possion()(泊松分布)

泊松分布,其参数有两个,分别是:\lambda系数(单位时间或单位面积内随机事件的平均发生率)、形状。例如:

  1. import numpy as np
  2. a = np.random.poisson(2)
  3. print(a)
  4. b = np.random.poisson(2,(2,3))
  5. print(b)
'
运行

结果如下:

  1. 2
  2. [[2 1 0]
  3. [2 1 4]]

4.1.7 np.random.permutation()  #产生乱序数组、打乱数组

产生一个乱序数组

当参数为整数n时,他返回 [0, n) 这n个整数的随机排列;

当参数为一个序列时,他返回这个序列的随机排列。

  1. import numpy as np
  2. r1 = np.random.permutation(6) #生成乱序数组
  3. print(r1)
  4. a = np.array([11,12,13,14,15,16]) #打乱数组
  5. r2 = np.random.permutation(a)
  6. print(r2)
'
运行

结果如下:

  1. [3 0 1 2 5 4]
  2. [12 11 16 13 15 14]

4.1.8 np.random.shuffle()  #打乱数组

将指定数组打乱,与permutation的区别是:

permutation将原数组中的元素打乱后放入新的数组中(产生了新的数组),对原数组没有影响;

shuffle直接改变原数组,将原数组打乱(不能产生新数组),是对原数组的操作,不能将其赋给新的变量

  1. import numpy as np
  2. a = np.array([11,12,13,14,15,16])
  3. r1 = np.random.permutation(a)
  4. print(r1)
  5. print(a)
  6. np.random.shuffle(a)
  7. print(a)
'
运行

结果如下:

  1. [11 16 14 15 12 13] # a打乱后赋值给r1
  2. [11 12 13 14 15 16] # a没有改变
  3. [16 12 13 14 15 11] # a被改变

4.1.9 np.random.choice()  #随机抽取

从指定样本中随机抽取

np.random.choice(ndarray, size = , replace = , p = )

size:用于指定输出数组的形状

replace:replace = True(默认)时,进行放回抽取;否则进行不放回抽取

p:指定每个元素的抽取概率(以列表或数组形式),如果不指定则默认为等概率抽取

当参数只有ndarray时,则返回随机抽取的一个数

  1. import numpy as np
  2. a = np.arange(10)
  3. r1 = np.random.choice(a)
  4. print(r1)
  5. r2 = np.random.choice(a,size = (2,3),replace = True,p = a/np.sum(a))
  6. print(r2)
'
运行

结果如下:

  1. 2
  2. [[1 7 5]
  3. [8 7 2]]

4.1.10 np.random.seed()  #种子

保证每次运行时出现相同的随机数,可以通过seed()指定随机数的种子

调用格式为:np.random.seed(num)

  1. import numpy as np
  2. np.random.seed(2)
  3. a = np.random.rand()
  4. print(a)
'
运行

结果如下:

0.43599490214200376(运行无数次都是这个结果)

4.2 求和、平均值、方差

函数总览:

函数名功能函数名功能
sum求和mean求期望
average加权平均数std标准差
var方差product连乘积

4.2.1 np.sum()  #求和

对指定元素进行求和,可以对所有元素求和,沿行(列)求和,对指定轴求和

  1. import numpy as np
  2. a = np.arange(2*3).reshape(2,3)
  3. print(a)
  4. r1 = np.sum(a) #对所有元素求和
  5. r2 = np.sum(a,axis = 0) #沿着行方向,对a的每一列求和
  6. r3 = np.sum(a,axis = 1,dtype = float) #沿着列方向,对a的每一行求和
  7. print(r1)
  8. print(r2)
  9. print(r3)
'
运行

 结果如下:

  1. [[0 1 2]
  2. [3 4 5]]
  3. 15
  4. [3 5 7]
  5. [ 3. 12.]

4.2.2 np.mean()  #求平均数

求数组的平均值,参数与sum()相同

  1. import numpy as np
  2. a = np.arange(2*3).reshape(2,3)
  3. print(a)
  4. r1 = np.mean(a)
  5. r2 = np.mean(a,axis = 0)
  6. print(r1)
  7. print(r2)
'
运行

结果如下:

  1. [[0 1 2]
  2. [3 4 5]]
  3. 2.5
  4. [1.5 2.5 3.5]

4.2.3 np.average()  #计算加权平均数

average()也可以进行平均计算,特殊点在于:他有一个weights参数,可以计算加权平均数

  1. import numpy as np
  2. score = np.array([88,90,93])
  3. number = np.array([15,25,30])
  4. result = np.average(score,weights = number)
  5. print(result)
'
运行

结果如下:

90.85714285714286'
运行

4.2.4 np.std()  #计算标准差

计算数组的标准差

np.std(ndarray, axis = , dtype= , out =  , ddof= )

ddof = 0(默认)时,计算偏样本标准差;ddof = 1时,计算无偏样本标准差

  1. import numpy as np
  2. a = np.array([1,2,3,4,5,6])
  3. r1 = np.std(a,axis = 0, ddof = 0)
  4. r2 = np.std(a,axis = 0, ddof = 1)
  5. print(r1)
  6. print(r2)
'
运行

结果如下:

  1. 1.707825127659933
  2. 1.8708286933869707
'
运行

4.2.5 np.var()  #计算方差

计算数组的方差,参数与np.std()一样

  1. import numpy as np
  2. a = np.array([1,2,3,4,5,6])
  3. r1 = np.var(a,axis = 0, ddof = 0)
  4. r2 = np.var(a,axis = 0, ddof = 1)
  5. print(r1)
  6. print(r2)
'
运行

结果如下:

  1. 2.9166666666666665
  2. 3.5
'
运行

4.2.6 np.product()  #计算所有元素乘积

计算数组中所有元素的乘积

参数与np.sum()类似

  1. import numpy as np
  2. a = np.array([1,2,3,4,5,6])
  3. r1 = np.product(a)
  4. print(r1)
'
运行

结果如下:

720'
运行

4.3 大小与排序

函数总览

函数名功能函数名功能
min最小值max最大值
minimum二元最小值maximum二元最大值
ptp极差argmin最小值的下标
argmax最大值的下标unravel_index一维下标转化成多维下标
sort数组排序argsort计算数组排序的下标
lexsort多列排序partition

快速计算前k位

argpartition前k位的下标median中位数
percentile百分位数searchsorted二分查找

4.3.1 np.min(),np.max(),np.minimum(),np.maximum(),np.ptp()

np.min(),np.max(),np.minimum(),np.maximum()分别表示计算最小值、最大值、二元最小值、二元最大值、极差

前四个函数的用法与np.sum()类似,np.ptp()有axis和out参数,用法与之前类似,这里例举最简单的情况:

  1. import numpy as np
  2. a = np.array([-1,6,4,-7,3,4])
  3. b = np.arange(2*3).reshape(2*3)
  4. print(a)
  5. r1 = np.min(a)
  6. r2 = np.max(a)
  7. r3 = np.ptp(a)
  8. print(r1)
  9. print(r2)
  10. print(r3)
  11. print(b)
  12. r4 = np.minimum(a,b) #对比a和b对应位置的元素,选出两个中最小的一个,放入新数组的对应位置
  13. r5 = np.maximum(a,b)
  14. r6 = np.ptp(b)
  15. print(r4)
  16. print(r5)
  17. print(r6)
'
运行

结果如下:

  1. [-1 6 4 -7 3 4] #a
  2. -7 #min
  3. 6 #max
  4. 13 #max-min
  5. [0 1 2 3 4 5] #b
  6. [-1 1 2 -7 3 4] #minimum
  7. [0 6 4 3 4 5] #maximum
  8. 5 #maximum-minimum

4.3.2 np.argmax(),np.argmin()  #求最值下标

可以求最大值和最小值的下标

如果不指定axis参数,则返回平坦化(转化成一维数组)之后的数组下标

如果指定axis参数,可以沿着指定轴计算最大值的下标

  1. import numpy as np
  2. a = np.random.randint(0,10,size = (2,3))
  3. r1 = np.argmax(a)
  4. print(a)
  5. print(r1)
'
运行

结果如下:

  1. [[8 9 0]
  2. [1 1 4]]
  3. 1

4.3.3 np.unravel_index()  #下标转化

可以将一维数组下标转化成多维数组的下标

np.unracel_index(下标, 多维数组的形状)

  1. import numpy as np
  2. a = np.random.randint(0,10,size = (2,3))
  3. r1 = np.argmax(a)
  4. print(a) #输出数组a
  5. print(r1) #最大值在数组平坦化后的下标
  6. r2 = np.unravel_index(r1,a.shape)
  7. print(r2) #最大值在原数组形状下的下标
'
运行

结果如下:

  1. [[6 0 1]
  2. [0 2 7]]
  3. 5
  4. (1, 2)

4.3.4 np.sort()  #排序

np.sort()可以对数组进行排序,并将排序后的值赋给新的数组

默认axis = 1(对每行数组进行排序)

axis = 0表示对每列数组进行排序

axis = None表示,将数组平坦化后进行排序

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.randint(0,10,size = (3,4))
  4. print(a)
  5. r1 = np.sort(a)
  6. r2 = np.sort(a,axis = 1)
  7. r3 = np.sort(a,axis = 0)
  8. r4 = np.sort(a,axis = None)
  9. print(r1)
  10. print(r2)
  11. print(r3)
  12. print(r4)
'
运行

结果如下:

  1. [[5 8 9 5]
  2. [0 0 1 7]
  3. [6 9 2 4]] #a
  4. [[5 5 8 9]
  5. [0 0 1 7]
  6. [2 4 6 9]] #r1
  7. [[5 5 8 9]
  8. [0 0 1 7]
  9. [2 4 6 9]] #r2
  10. [[0 0 1 4]
  11. [5 8 2 5]
  12. [6 9 9 7]] #r3
  13. [0 0 1 2 4 5 5 6 7 8 9 9] #r4

4.3.5 np.argsort()  #排序后的下标

np.argsort()返回数组的排序下标,参数axis默认为-1

  1. import numpy as np
  2. np.random.seed(69)
  3. a = np.random.randint(0,10,size = (5,))
  4. print(a)
  5. r1 = np.argsort(a)
  6. print(r1)
'
运行

结果如下:

  1. [6 9 7 4 1]
  2. [4 3 0 2 1]

即:a中1是最小的,其下标是4,所以4在r1[0];

以此类推,4是a中第二小的,其下标为3,所以3在r1[1]

4.3.6 np.lexsort()  #多列排序

np.lexsort()类似于Excel中的多列排序,其参数为一个形状为(k, N)的数组,即包含k个长度为N的序列,可以理解成N行k列的表格,该方法返回排序下标,数组中最后的行为排序的主键(以数组中最后一行为标准进行排列)

例如:

  1. import numpy as np
  2. np.random.seed(69)
  3. name = ['A','B','C','D','E']
  4. age = [31,35,40,29,25]
  5. r1 = np.lexsort([name,age]) #参数是一个2行5列的数组
  6. print(r1)
'
运行

结果如下:

[4 3 0 1 2]

即,以最后一行(age)为标准进行排序,所以返回age的下标排序

4.3.6 np.lexsort() 应用:成绩姓名全局排序

背景:A、B等5人乘积分别是95,93,87,99,96,将姓名与成绩对应,并按成绩由大到小排列

  1. import numpy as np
  2. np.random.seed(69)
  3. name = ['A','B','C','D','E']
  4. score = [95,93,87,99,96]
  5. idx = np.lexsort([name,score])
  6. print(idx)
  7. r1 = list(zip(name,score))
  8. l = []
  9. for i in idx:
  10. l.append(r1[i])
  11. print(l)
'
运行

结果如下: 

  1. [2 1 0 4 3]
  2. [('C', 87), ('B', 93), ('A', 95), ('E', 96), ('D', 99)]

4.3.7 np.partition(),np.argpartition()  #数组分割

np.partition(),np.argpartition()可以对数组进行分割,快速找出排序后数组的前k个元素(调用速度比sort()快很多)

np.partition(ndarray, kth = )

调用后,使新数组前kth个元素是原数组中最小的kth个,且这kth个也不按大小排序,只是把他们挑出来放在新数组的前面而已,剩余的放在后面随便排,例如:

  1. import numpy as np
  2. np.random.seed(69)
  3. a = np.random.randint(0,10,size = (10,))
  4. print(a)
  5. r1 = np.partition(a,kth = 7)
  6. print(r1)
'
运行

结果如下:

  1. [6 9 7 4 1 6 9 8 1 6]
  2. [6 1 1 4 6 7 6 8 9 9]

即:r1的前7个元素是a中最小的7个,且在r1中没有按大小排序,只是把它们挑出来放在前七个位置上而已,后面的8,9,9是随便排的

如果需要将前7个排序,再调用一下np.sort()就可以:

  1. import numpy as np
  2. np.random.seed(69)
  3. a = np.random.randint(0,10,size = (10,))
  4. print(a)
  5. r1 = np.partition(a,kth = 7)
  6. print(r1)
  7. r2 = np.sort(r1[:7])
  8. print(r2)
'
运行

结果如下:

  1. [6 9 7 4 1 6 9 8 1 6]
  2. [6 1 1 4 6 7 6 8 9 9]
  3. [1 1 4 6 6 6 7]

 np.argpartition()同理,只是返回的是下标而已:

  1. import numpy as np
  2. np.random.seed(69)
  3. a = np.random.randint(0,10,size = (10,))
  4. print(a)
  5. r1 = np.argpartition(a,kth = 7)
  6. print(r1)
  7. r2 = np.sort(a[r1[:7]])
  8. print(r2)
'
运行

 结果如下:

  1. [6 9 7 4 1 6 9 8 1 6]
  2. [5 4 8 3 0 2 9 7 6 1]
  3. [1 1 4 6 6 6 7]

4.3.8 np.median()  #计算中位数

np.median()可以获得数组的中值,即:先把数组排序,再取中值。当长度是偶数时,取中间两个数的平均数

可以指定axis参数

  1. import numpy as np
  2. np.random.seed(69)
  3. a = np.random.randint(0,5,size = (5,))
  4. print(np.sort(a))
  5. r1 = np.median(a)
  6. print(r1)
  7. b = np.random.randint(0,6,size = (6,))
  8. print(np.sort(b))
  9. r2 = np.median(b)
  10. print(r2)
'
运行

结果如下:

  1. [1 2 3 3 4]
  2. 3.0
  3. [0 0 0 1 1 1]
  4. 0.5

4.3.9 np.percentile()  #计算百分数

np.percentile()用于计算百分数,即:将元素从小大到排列,计算处于p%位置上的值

调用格式及参数:np.percentile(ndarray, p),其中p可以是一个数,也可以是一个数组

  1. import numpy as np
  2. a = np.array([1,2,3,4,5,6,7,8,9,10])
  3. print(a)
  4. r1 = np.percentile(a,[0,25,50,75,100])
  5. print(r1)
'
运行

结果如下:

  1. [ 1 2 3 4 5 6 7 8 9 10]
  2. [ 1. 3.25 5.5 7.75 10. ]

4.3.10 np.searchsorted()  #插入元素(二分查找)

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

  1. import numpy as np
  2. a = np.array([2,2,2,2,4,8,16,32])
  3. print(a)
  4. r1 = np.searchsorted(a,2,side = 'left')
  5. print(r1)
  6. r2 = np.searchsorted(a,2,side = 'right')
  7. print(r2)
'
运行

结果如下:

  1. [ 2 2 2 2 4 8 16 32]
  2. 0
  3. 4

若a中没有value中的元素:

        将value的各个元素插入到a的合适位置,使插入后的元素value满足:

            当side = left(默认)时:a[i-1] < value <= a[i](局部升序)

            当side = right时:a[i-1] <= value < a[i](局部升序)

  1. import numpy as np
  2. a = np.array([2,4,8,16,32])
  3. print(a)
  4. r1 = np.searchsorted(a,[1,3,5,7,9,11])
  5. print(r1)
  6. r2 = np.searchsorted(a,[1,3,5,7,9,11],side = 'right')
  7. print(r2)
'
运行

结果如下:

  1. [ 2 4 8 16 32]
  2. [0 1 2 2 3 3]
  3. [0 1 2 2 3 3]

4.4 统计函数

函数总览:

函数名功能函数名功能
unique去除重复元素bincount对整数数组的元素计数
histogram一维直方图统计

4.4.1 np.unique()  #去除重复元素

np.unique()返回去除重复元素后的数组,并按从小到大的顺序排列

np.unique(ndarray, return_index, return_inverse)

return_index:为True时,返回:新数组在原数组中的下标组成的数组,默认为False

return_inverse:为True时,返回:原始数组在新数组中的下标组成的数组,默认为False

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.randint(0,10,size = (10,))
  4. print(a)
  5. r1 = np.unique(a,return_index = True,return_inverse = True)
  6. print(r1)
'
运行

结果如下:

  1. [5 8 9 5 0 0 1 7 6 9]
  2. (array([0, 1, 5, 6, 7, 8, 9]), #新数组
  3. array([4, 6, 0, 8, 7, 1, 2], dtype=int64),
  4. array([2, 5, 6, 2, 0, 0, 1, 4, 3, 6], dtype=int64))

4.4.2 np.bincount()  #对整数数组的元素计数

np.bincount()对整数数组中各个元素的出现次数进行统计,要求原数组必须是非负的

np.bincount(ndarray, weights = )

返回一个数组,数组中下标为i的元素表示:数字i出现的次数

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.randint(0,10,size = (10,))
  4. print(a)
  5. r1 = np.bincount(a)
  6. print(r1)
'
运行

结果如下:

  1. [5 8 9 5 0 0 1 7 6 9]
  2. [2 1 0 0 0 2 1 1 1 2]

即:0出现2次,1出现1次,3出现0次…… 

参数weights可以指定一个数组w,表示每个数所对应的权值。

返回数组a中的每个整数所对应的w中的权值之和,例如:

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.randint(0,4,size = (5,))
  4. print(a)
  5. w = np.array([0.1,0.2,0.3,0.4,0.5])
  6. print(w)
  7. r1 = np.bincount(a,weights = w)
  8. print(r1)
'
运行

结果如下:

  1. [1 3 0 0 3]
  2. [0.1 0.2 0.3 0.4 0.5]
  3. [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]

4.4.3 np.histogram()  #直方图统计

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,每两个相邻数值构成一个统计区间

例如:

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.rand(100)
  4. r1 = np.histogram(a,bins = 5,range = (0,1))
  5. print(r1)
'
运行

结果如下:

  1. (array([24, 16, 21, 20, 19], dtype=int64),
  2. 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之间……

4.5 分段函数

函数总览

函数名功能函数名功能
where

矢量化判断表达式

piecewise分段函数
select多分支判断选择

4.5.1 np.where()  #if

x = np.where(condition, y, z)

其中condition, y, z都是数组,其返回值是一个形状与condition相同的数组

当condition中的某个元素为True时,x中对应下标的值从数组y获取,否则从z获取

  1. import numpy as np
  2. np.random.seed(1)
  3. x = np.random.randint(0,10,size = (5,))
  4. print(x)
  5. y = np.where(x<5,'yes','no')
  6. print(y)
'
运行

结果如下:

  1. [5 8 9 5 0]
  2. ['no' 'no' 'no' 'no' 'yes']

4.5.2 np.select()  #多分支的if

如果分段函数分段的数量很多,就需要用np.where()一层一层嵌套,不利于编写与阅读用np.select()就可以解决这个问题

select(condlist, choicelist, default = 0)

condlist:长度为N的布尔数组列表(必须是列表形式),用于判断分段的条件(例如x是否<5)

choicelist:长度为N的储存候选值的数组列表(必须是列表形式),用于具体计算

default:当所有条件都不满足时,用default填上

关于布尔数组,例如:

  1. import numpy as np
  2. np.random.seed(1)
  3. a = np.random.randint(0,10,size = 5)
  4. print(a)
  5. x = [a<5] #布尔数组
  6. print(x)
'
运行

结果如下:

  1. [5 8 9 5 0]
  2. [array([False, False, False, False, True])]

对于np.select的具体用法,

例如:分段函数:x<5时,y=x**2;5<=x<=10时,y=-x;x>10时,y=0

  1. import numpy as np
  2. np.random.seed(5)
  3. x = np.random.randint(0,15,size = 10)
  4. print(x)
  5. #指明自变量分段的条件
  6. condition = [x<5,
  7. np.logical_and(x>=5,x<=10), #用逻辑运算,Python不支持5<=x<=10
  8. x>10]
  9. #指明各段的函数
  10. choice = [x**2,-x,0]
  11. y = np.select(condition,choice)
  12. print(y)
'
运行

结果如下:

  1. [ 3 14 13 6 6 0 9 8 4 7]
  2. [ 9 0 0 -6 -6 0 -9 -8 16 -7]

4.5.3 np.piecewise()  #分段函数

尽管用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

  1. import numpy as np
  2. np.random.seed(5)
  3. x = np.random.randint(0,15,size = 10)
  4. print(x)
  5. #指明自变量分段的条件
  6. condition = [x<5,
  7. np.logical_and(x>=5,x<=10), #用逻辑运算,Python不支持5<=x<=10
  8. x>10]
  9. #指明各段的函数,此处需要用lambda
  10. funclist = [lambda x:x**2,
  11. lambda x:-x,
  12. 0]
  13. y = np.piecewise(x,condition,funclist)
  14. print(y)
'
运行

结果如下:

  1. [ 3 14 13 6 6 0 9 8 4 7]
  2. [ 9 0 0 -6 -6 0 -9 -8 16 -7]

4.6 操作多维数组

函数总览

函数名功能函数名功能
concatenate连接多个数组vstack沿第0轴连接数组
hstack、c_[]沿第1轴连接数组column_stack按列连接多个一维数组
split、array_split将数组分为多段transpose重新设置轴的顺序
swapaxes交换两个轴的顺序

4.6.1 np.concatenate()  #连接多个数组

用于连接多个数组,第一个参数为需要连接的数组,用()括起来,第二个参数是axis,用于指定沿axis轴进行连接,默认为0

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.zeros((3,3))
  4. b = np.ones((3,3))
  5. r1 = np.concatenate((a,b))
  6. print(r1)
  7. r2 = np.concatenate((a,b),axis = 1)
  8. print(r2)
'
运行

结果如下:

  1. [[0. 0. 0.]
  2. [0. 0. 0.]
  3. [0. 0. 0.]
  4. [1. 1. 1.]
  5. [1. 1. 1.]
  6. [1. 1. 1.]]
  7. [[0. 0. 0. 1. 1. 1.]
  8. [0. 0. 0. 1. 1. 1.]
  9. [0. 0. 0. 1. 1. 1.]]

4.6.2 np.vstack()  #沿第0轴连接数组

np.vstack()用于沿着第0轴连接数组,当被连接数组是长度为N的一维数组时,将其形状改为(1, N)

其参数为要连接的数组,用()括起来

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.zeros((3,3))
  4. b = np.ones((3,3))
  5. r1 = np.vstack((a,b))
  6. print(r1)
'
运行

结果如下:

  1. [[0. 0. 0.]
  2. [0. 0. 0.]
  3. [0. 0. 0.]
  4. [1. 1. 1.]
  5. [1. 1. 1.]
  6. [1. 1. 1.]]

4.6.3 np.hstack()  #沿第1轴连接数组

与np.vstack()相似,沿着第1轴连接数组,当所有数组都是一维时,沿着第0周连接数组

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.zeros((3,3))
  4. b = np.ones((3,3))
  5. r1 = np.hstack((a,b))
  6. print(r1)
'
运行

结果如下:

  1. [[0. 0. 0. 1. 1. 1.]
  2. [0. 0. 0. 1. 1. 1.]
  3. [0. 0. 0. 1. 1. 1.]]

4.6.4 np.c[]  #按列连接多个一维数组

和np.hstack()一样,按列连接数组

调用格式为:np.c_[a,b]

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.zeros((3,3))
  4. b = np.ones((3,3))
  5. r1 = np.c_[a,b]
  6. print(r1)
'
运行

结果如下:

  1. [[0. 0. 0. 1. 1. 1.]
  2. [0. 0. 0. 1. 1. 1.]
  3. [0. 0. 0. 1. 1. 1.]]

4.6.5 np.split()、np.array_split()  #将数组分为多段

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为整数时):

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.arange(1,10).reshape(3,3)
  4. print(a)
  5. r1 = np.split(a,3) # indices_or_sections为整数
  6. print(r1)
  7. A,B,C = np.split(a,3) # indices_or_sections为整数
  8. print(A)
  9. print(B)
  10. print(C)
'
运行

结果如下:

  1. [[1 2 3]
  2. [4 5 6]
  3. [7 8 9]]
  4. [array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]
  5. [[1 2 3]]
  6. [[4 5 6]]
  7. [[7 8 9]]

2.当 indices_or_sections为数组时(axis = 0):

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.arange(5*6).reshape(5,6)
  4. print(a)
  5. A,B,C = np.split(a,[1,4])
  6. print(A)
  7. print(B)
  8. print(C)
'
运行

结果如下:

  1. [[ 0 1 2 3 4 5]
  2. [ 6 7 8 9 10 11]
  3. [12 13 14 15 16 17]
  4. [18 19 20 21 22 23]
  5. [24 25 26 27 28 29]]
  6. #横向切(横着切),在纵向下标为1和4处分隔
  7. [[0 1 2 3 4 5]]
  8. [[ 6 7 8 9 10 11]
  9. [12 13 14 15 16 17]
  10. [18 19 20 21 22 23]]
  11. [[24 25 26 27 28 29]]

3.当 indices_or_sections为数组时(axis = 0):

  1. import numpy as np
  2. np.random.seed(5)
  3. a = np.arange(5*6).reshape(5,6)
  4. print(a)
  5. A,B,C = np.split(a,[1,4],axis = 1)
  6. print(A)
  7. print(B)
  8. print(C)
'
运行

结果如下:

  1. [[ 0 1 2 3 4 5]
  2. [ 6 7 8 9 10 11]
  3. [12 13 14 15 16 17]
  4. [18 19 20 21 22 23]
  5. [24 25 26 27 28 29]]
  6. #纵向切(竖着切),在横向下标为1和4处分隔
  7. [[ 0]
  8. [ 6]
  9. [12]
  10. [18]
  11. [24]]
  12. [[ 1 2 3]
  13. [ 7 8 9]
  14. [13 14 15]
  15. [19 20 21]
  16. [25 26 27]]
  17. [[ 4 5]
  18. [10 11]
  19. [16 17]
  20. [22 23]
  21. [28 29]]

4.6.6 np.transpose()、np.swapaxes()  #重新设置轴的顺序

np.transpose()用于修改轴的顺序

例如:np.transpose(a,[1,2,0])表示:新数组的第0轴存放a的第1轴,新数组的第1轴存放a的第2轴,新数组的第2轴存放a的第0轴

  1. import numpy as np
  2. a = np.arange(1*2*3).reshape(1,2,3)
  3. print(a.shape)
  4. r1 = np.transpose(a,[1,2,0])
  5. print(r1.shape)
'
运行

结果如下:

  1. (1, 2, 3)
  2. (2, 1, 3)
'
运行

4.6.7 np.swapaxes()  #交换两个轴的顺序

np.swapaxes()用于交换两个轴的顺序

例如:np.swapaxes(a,0,1)表示:将a的第0轴和第1轴交换顺序

  1. import numpy as np
  2. a = np.arange(2*3*4).reshape(2,3,4)
  3. print(a.shape)
  4. r1 = np.swapaxes(a,0,1)
  5. print(r1.shape)
'
运行

结果如下:

  1. (2, 3, 4)
  2. (3, 2, 4)
'
运行

4.7 多项式函数

4.7.1 np.poly1d()  #转化成poly1d对象

np.poly1d()可以将列表、数组转化成poly1d对象,该对象可以像函数一样调用

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. r1 = np.poly1d(a)
  4. print(r1)
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x + 3

即表示:x^{2}+2x+3

用法1:可以像函数一样被调用:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. f = np.poly1d(a)
  4. print(f)
  5. r1 = f(2) #x=2带入
  6. print(r1)
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x + 3
  3. 11 #表示x=2时上式的结果

用法2:多项式的四则运算

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. f = np.poly1d(a)
  4. print(f)
  5. print(f + [5,5])
  6. print(f*2)
  7. print(f*f)
  8. print(f/[1,3])
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x - 3 # f
  3. 2
  4. 1 x + 7 x + 2 # f + [5,5]
  5. 2
  6. 2 x + 4 x - 6 # f*2
  7. 4 3 2
  8. 1 x + 4 x - 2 x - 12 x + 9 # f*f
  9. (poly1d([ 1., -1.]), poly1d([0.])) #f/[1,3]
  10. #返回两个poly1d类型的元素,第一个是商,第二个是余数

4.7.2 deriv()  #计算微分

deriv()用于计算多项式函数的微分,调用格式为:poly1d对象.deriv()

  1. import numpy as np
  2. a = np.array([1,2,-3])
  3. f = np.poly1d(a)
  4. print(f)
  5. r1 = f.deriv()
  6. print(r1)
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x - 3
  3. 2 x + 2

4.7.3 integ()  #计算积分

integ()用于计算多项式函数的积分,调用格式为:poly1d对象.integ()

  1. import numpy as np
  2. a = np.array([1,2,-3])
  3. f = np.poly1d(a)
  4. print(f)
  5. r1 = f.integ()
  6. print(r1)
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x - 3
  3. 3 2
  4. 0.3333 x + 1 x - 3 x

4.7.4 np.roots()  #求根

np.roots()用于计算多项式函数的根,调用格式为:np.roots(poly1d对象)

  1. import numpy as np
  2. a = np.array([1,2,-3])
  3. f = np.poly1d(a)
  4. print(f)
  5. r1 = np.roots(f)
  6. print(r1)
'
运行

结果如下:

  1. 2
  2. 1 x + 2 x - 3
  3. [-3. 1.]

4.7.5 np.poly()  #用根求多项式方程

np.poly()可以通过根求多项式系数

  1. import numpy as np
  2. a = np.array([1,2])
  3. r1 = np.poly(a)
  4. print(r1)
'
运行

结果如下:

[ 1. -3.  2.]

4.7.6 np.polyfit()  #拟合多项式函数

np.polyfit():根据数据拟合出相应的多项式函数,找出与这组数据的误差平方最小的多项式的系数

np.polyfit(x, y, 最高次的次数)

  1. import numpy as np
  2. a = np.array([1,2,3,4,5])
  3. b = np.array([1,4,9,16,25])
  4. r1 = np.polyfit(a,b,3)
  5. print(r1)
'
运行

结果如下:

[ 1.62920807e-17  1.00000000e+00 -4.54973822e-15  2.70557374e-15]

4.8 多项式函数类

np.polynomial中提供了更丰富的多项式函数类,其中多项式各项的系数按照幂从小到大的顺序排列(与4.7相反)

4.8.1 np.polynomial.Polynomial()  #创建Polynomial对象

np.polynomial.Polynomial()可以创建Polynomial对象,并计算多项式函数

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. f = np.polynomial.Polynomial(a)
  4. r1 = f(2) #计算1*(2^0) + 2*(2^1) + 3*(2^2)
  5. print(r1)
'
运行

结果如下:

17.0'
运行

4.8.2 p.deriv()  #计算导函数

对于Ploynomial对象,p.deriv()可以计算导函数:

  1. import numpy as np
  2. a = np.array([1,2,3])
  3. f = np.polynomial.Polynomial(a)
  4. r1 = f.deriv()
  5. print(r1)
'
运行

结果如下:

poly([2. 6.])

即:1+2x+3x^{2},求导得 2+6x

4.8.3 np.polynomial.Chebyshev()(拓展)

切比雪夫多项式是一个正交多项式序列T_{i}(x),一个n次多项式可以表示为多个切比雪夫多项式的加权和

使用Chebyshev类表示由切比雪夫多项式组成的多项式p(x)=\sum_{i=0}^{n}c_{i}T_{i}(x)

T_{i}(x)多项式可由Chebyshev.basis(i)获得

1.利用convert方法转换多项式类型

语句:Chebyshev.basis(i).convert(kind = )

例如:将T_{4}(x)转化成Polynomial类:

  1. import numpy as np
  2. a = np.polynomial.Chebyshev.basis(4)
  3. print(a)
  4. r1 = a.convert(kind = np.polynomial.Polynomial)
  5. print(r1)
'
运行

结果如下:

  1. cheb([0. 0. 0. 0. 1.])
  2. poly([ 1. 0. -8. 0. 8.])

即:T_{4}(x)=1-8x^{2}+8x^{4}

2.切比雪夫节点

切比雪夫多项式的根称为切比雪夫节点可以用于多项式插值。相应的差值多项式能最大程度降低龙格现象(等距插值多项式在两端有很大的振荡),并且提供多项式在连续函数的最佳一致逼近。

详细查看(p101)

4.9 各种乘积运算

函数总览

函数名功能函数名功能
dot矩阵乘积inner内积
outer外积tensordot张量乘积

4.9.1 np.dot()  #矩阵乘积

对于一维数组,其计算内积;对于二维数组,其计算矩阵乘积

通用公式:dot(a, b)[i, j, k, m] = sum(a[i, j, :] * b[k , :, m])

对于一维数组:直接计算内积,即向量点乘

  1. import numpy as np
  2. #一维数组
  3. a = np.arange(3)
  4. b = np.array([2,3,4])
  5. print(a)
  6. print(b)
  7. r1 = np.dot(a,b)
  8. print(r1)
'
运行

结果如下:

  1. [0 1 2]
  2. [2 3 4]
  3. 11 # 0*2 + 1*3 + 2*4

对于二维数组:进行矩阵乘法(第一行乘第一列,m*n与n*k才能相乘)

  1. import numpy as np
  2. # 二维数组
  3. a = np.arange(6).reshape(3,2)
  4. b = np.array([[2,3,4],[5,6,7]])
  5. print(a)
  6. print(b)
  7. r1 = np.dot(a,b)
  8. print(r1)
'
运行

结果如下:

  1. [[0 1]
  2. [2 3]
  3. [4 5]]
  4. [[2 3 4]
  5. [5 6 7]]
  6. [[ 5 6 7]
  7. [19 24 29]
  8. [33 42 51]]

4.9.2 np.inner()  #内积

np.inner()用于计算内积

对于一维数组,inner()和dot()一样,

对于二维数组,具体计算过程见下例

计算内积时,需保证两个矩阵形状相同!!!

  1. import numpy as np
  2. # 二维数组
  3. a = np.arange(6).reshape(2,3)
  4. b = np.array([[2,3,4],[5,6,7]])
  5. print(a)
  6. print(b)
  7. r1 = np.inner(a,b)
  8. print(r1)
'
运行

结果如下:

  1. [[0 1 2] # a行
  2. [3 4 5]] # b行
  3. [[2 3 4] # c行
  4. [5 6 7]] # d行
  5. [[11 20] # [a*c a*d]
  6. [38 74]] # [b*c b*d]

4.9.3 np.outer()  #外积

np,outer()用于计算外积,且只对一维数组进行计算,如果传入的是多维数组,先将数组展平为一维数组再计算(具体计算过程见下例)

对于一维数组:

  1. import numpy as np
  2. # 一维数组
  3. a = np.arange(3)
  4. b = np.array([2,3,4])
  5. print(a)
  6. print(b)
  7. r1 = np.outer(a,b)
  8. print(r1)
'
运行

结果如下:

  1. [0 1 2]
  2. [2 3 4]
  3. [[0 0 0] # [0*2 0*3 0*4] 或 [a11*b11 a11*b12 a11*b13]
  4. [2 3 4] # [1*2 1*3 1*4]
  5. [4 6 8]] # [2*2 2*3 2*4]

对于二维数组:

  1. import numpy as np
  2. # 二维数组
  3. a = np.arange(6).reshape(2,3)
  4. b = np.array([[2,3,4],[5,6,7]])
  5. print(a)
  6. print(b)
  7. r1 = np.outer(a,b)
  8. print(r1)
'
运行

结果如下:

  1. [[0 1 2]
  2. [3 4 5]]
  3. [[2 3 4]
  4. [5 6 7]]
  5. [[ 0 0 0 0 0 0] # [0*2 0*3 0*4 0*5 0*6 0*7]
  6. [ 2 3 4 5 6 7] # [1*2 1*3 1*4 1*5 1*6 1*7]
  7. [ 4 6 8 10 12 14] # ……
  8. [ 6 9 12 15 18 21]
  9. [ 8 12 16 20 24 28]
  10. [10 15 20 25 30 35]]

4.9.4 np.tensordot()  #张量乘积

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个轴进行相乘再相加的运算,其他轴保持不变

  1. import numpy as np
  2. # 二维数组
  3. a = np.arange(9).reshape(3,3)
  4. b = np.array([[2,3,4],[5,6,7],[8,9,10]])
  5. print(a)
  6. print(b)
  7. r1 = np.tensordot(a,b,axes = [[0],[0]]) #表示a的列和b的列相乘,放在a11……
  8. print(r1)
'
运行

结果如下:

  1. [[0 1 2]
  2. [3 4 5]
  3. [6 7 8]]
  4. [[ 2 3 4]
  5. [ 5 6 7]
  6. [ 8 9 10]]
  7. [[ 63 72 81]
  8. [ 78 90 102]
  9. [ 93 108 123]]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/968982
推荐阅读
相关标签
  

闽ICP备14008679号