整体操作numpy数组的方法
说在前面
 
numpy数组支持与标量的加、减、乘、除和幂等算术运算,计算结果为一个新数组,其元素为标量与原数组每个元素进行计算的结果。演示代码如下:
2. numpy 数学函数和算术函数>> a = np.arange(8)>> a.shape = (2, 4) #修改数组形状为2行4列>> aarray([[0, 1, 2, 3],[4, 5, 6,7]])>> a + 2array([[2, 3, 4, 5],[6, 7, 8,9]])>> a - 2array([[-2, -1, 0, 1],[ 2, 3, 4, 5]])>> a * 2array([[ 0, 2, 4, 6],[ 8, 10,12, 14]])>> a / 2array([[0. , 0.5, 1. , 1.5],[2. ,2.5, 3. , 3.5]])>> a // 2array([[0, 0, 1, 1],[2, 2, 3,3]], dtype=int32)>> a % 2array([[0, 1, 0, 1],[0, 1, 0,1]], dtype=int32)>> a ** 2 #分别计算0**2,1**2,2**2,…,7**2array([[ 0, 1, 4, 9],[16, 25,36, 49]], dtype=int32)>> 2 ** a #分别计算2**0,2**1,2**2,…,2**7array([[ 1, 2, 4, 8],[16, 32, 64, 128]], dtype=int32)
numpy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。
numpy 提供了标准的三角函数:sin()、cos()、tan()。arcsin()、arccos()和arctan()函数返回给定角度的 sin,cos 和 tan 的反三角函数。这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。
numpy.abs() 函数返回各元素的绝对值。
numpy.around() 函数返回指定数字的四舍五入值。
numpy.floor()函数返回小于或者等于指定表达式的最大整数,即向下取整。
numpy.ceil()函数返回大于或者等于指定表达式的最小整数,即向上取整。
numpy.reciprocal()函数返回各元素的倒数,如1/4 倒数为 4/1。
3. numpy数组与数组的运算(1)形状相同的数组进行算术运算。
可以对两个形状相同的numpy数组进行算术运算,得到一个新数组,其元素的值为原来的两个数组中对应位置上元素进行运算的结果。演示代码如下:
> a =np.array([[1,3,5,7,9],[2,4,6,8,10]])> aarray([[ 1, 3, 5, 7, 9],[ 2, 4, 6, 8,10]])> b = np.array([[1,2,3,4,5],[10,9,8,7,6]])> barray([[ 1, 2, 3, 4, 5],[10, 9, 8, 7, 6]])> a + barray([[ 2, 5, 8,11, 14],[12, 13, 14, 15, 16]])> a - barray([[ 0, 1, 2, 3, 4],[-8, -5, -2, 1, 4]])> a * barray([[ 1, 6, 15, 28, 45],[20, 36, 48, 56, 60]])> a / barray([[1. , 1.5 , 1.66666667, 1.75 , 1.8 ],[0.2 , 0.44444444, 0.75 , 1.14285714, 1.66666667]])> a % barray([[0, 1, 2, 3, 4],[2, 4, 6, 1, 4]], dtype=int32)> a ** barray([[ 1, 9, 125, 2401, 59049],[ 1024, 262144, 1679616, 2097152, 1000000]],dtype=int32)
(2)numpy数组广播机制。
当运算中的 2个数组的形状不同时,numpy将自动触发广播机制。演示代码如下:
> a = np.array([[ 0, 0,0],[10,10,10],[20,20,20],[30,30,30]])> b = np.array([1,2,3])> a + barray([[ 1, 2, 3],[11, 12,13],[21, 22,23],[31, 32,33]])
图1-2展示了数组b如何通过广播来与数组a兼容。

图1-2
注意:若想要两个数组通过广播机制来实现兼容,则其中某个数组的维度必须为1(即只有1行或1列);若条件不满足,则抛出异常。演示代码如下:
> a =np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])> b = np.array([[1],[2],[3],[4]])> a + barray([[ 2, 3, 4, 5],[ 7, 8, 9,10],[12, 13,14, 15],[17, 18,19, 20]])> c = np.array([[1, 2],[3, 4]])> a + cTraceback (most recent call last):File"" , line 1, in <module>a + cValueError: operands could not be broadcast togetherwith shapes (4,4) (2,2)
(3)连接数组。
concatenate()函数用于沿指定轴连接相同维度的两个或多个数组,函数格式如下:
np. concatenate((a1, a2, ...), axis=0)
其中a1, a2, ...表示多个相同维度的数组;axis表示沿着它连接数组的轴,值为0时增加行数,值为1时增加列数。演示代码如下:
> a = np.array([[1,2],[3,4],[5,6]])> aarray([[1, 2],[3, 4],[5, 6]])> b = np.array([[4, 5],[6,7]])> barray([[4, 5],[6, 7]])> np.concatenate((a,b),axis=0) #沿轴0连接两个数组,要确保列数相同array([[1, 2],[3, 4],[5, 6],[4, 5],[6, 7]])> c = np.array([[1],[2],[3]])> carray([[1],[2],[3]])> np.concatenate((a,c),axis=1) #沿轴1连接两个数组,要确保行数相同array([[1, 2, 1],[3, 4,2],[5, 6,3]])
(1)where()函数
与使用布尔索引访问数组类似,numpy模块提供了where()函数来返回数组中满足条件的索引数组,或根据数组中的元素是否满足指定条件来决定取值x还是y,其语法格式如下:
numpy.where(condition[,x,y])
该函数有一个必选参数condition,通过判断原数组的每个元素是否满足条件,返回一个由满足条件的元素的索引构成的数组;x,y是可选参数,如果条件为真,则返回x,否则返回y。
如果只有一个condition参数,则该函数返回索引数组,或者是由索引数组构成的元组(多维数组);如果是有三个参数,则返回由x和y值构成的数组。演示代码如下:
>> a = np.arange(1, 11)>> aarray([ 1, 2, 3, 4, 5, 6, 7, 8, 9,10])>> np.where(a % 2 == 1) #提供1个参数,只返回满足条件的索引数组(array([0, 2, 4, 6, 8], dtype=int64),)>> a[np.where(a % 2 ==1)] #使用索引重构原数组array([1, 3, 5, 7, 9])>> np.where(a % 2 == 1, 1,0) #提供3个参数,满足条件取值1,否则取值0array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0])>>a=np.array([[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8]]) #二维数组>> aarray([[1, 2, 3, 4,5],[2, 3, 4, 5, 6],[3, 4, 5, 6, 7],[4, 5, 6, 7, 8]])>> i =np.where((a>4) & (a<7)) #提供1个参数,只返回满足条件的索引数组>> i #因为a是二维数组,故i为由索引数组构成的元组,分别存储了满足条件的数组元素的行索引和列索引(array([0, 1, 1, 2,2, 3, 3], dtype=int64), array([4, 3, 4, 2, 3, 1, 2], dtype=int64))>> a[i] #使用索引重构原数组,相当于使用整数数组索引访问数组array([5, 5, 6, 5,6, 5, 6])>> a[[0,1, 1, 2, 2, 3, 3],[4, 3, 4, 2, 3, 1, 2]] #使用整数数组索引访问数组array([5, 5, 6, 5,6, 5, 6])>> np.where(a % 2 == 1, 1, 0)#提供3个参数,满足条件取值1,否则取值0array([[1, 0, 1, 0, 1],[0, 1, 0, 1, 0],[1, 0, 1, 0, 1],[0, 1, 0, 1, 0]])>> np.where(a % 2 == 1, a*2, a//2) #提供3个参数,奇数翻倍,偶数减半array([[ 2, 1, 6, 2, 10],[ 1, 6, 2,10, 3],[ 6, 2, 10, 3, 14],[ 2,10, 3, 14, 4]])
(2)piecewise()函数
piecewise()函数用来筛选满足不同条件的元素,函数格式如下:
np.piecewise(x, condlist, funclist,*args, **kw)
关键参数说明:
x表示要进行操作的对象;condlist表示要满足的条件列表,可以是多个条件构成的列表;funclist是执行的操作列表,它与参数condlist是对应的,当条件为True时,则执行相对应的操作函数。返回一个array对象,和原始操作对象x具有完全相同的维度和形状。
例如,随机生成一个numpy数组a存储学生成绩,为学生设置1、2、3、4四个等级;临界分数分别为60、80和90分。演示代码如下:
a = np.random.randint(0, 101, 6)print(a)b = np.piecewise(a,[a<60,((60<=a)&(a<80)),((80<=a)&(a<90)),a>=90],[1, 2,3, 4])print(b)
(1)随机生成一个二维numpy数组a,将数组中小于0的置零大于零的保留原值。
参考代码如下:
a = np.random.randint(-10, 10, (2, 3)) #生成2行3列元素值介于[-10,10)的随机整数print(a)#方法一:where()函数b = np.where(a>0, a, 0)print(b)#方法二:abs()函数b = (a + np.abs(a)) // 2print(b)#方法三:布尔索引a[a<0] = 0print(a)
(2)随机生成一个二维numpy数组a,对数组元素做y=2*x*x-3*x+5的运算(连续函数)。
参考代码如下:
a = np.random.randint(-10, 10, (2, 3)) #生成2行3列元素值介于[-10,10)的随机整数print(a)def fun(x): #连续函数return2*x*x-3*x+5b = fun(a)print(b)
(3)随机生成一个二维numpy数组a,对数组元素做y=4*x-3(x>0),y=2*x+6(x<=0)的运算(非连续函数)。
参考代码如下:
a = np.random.randint(-10, 10, (2, 3)) #生成2行3列元素值介于[-10,10)的随机整数print(a)def fun2(x): #非连续函数if x > 0:y =4*x-3else:y = 2*x+6return yfun_vec = np.vectorize(fun2) #先对fun2进行向量化处理b = fun_vec(a) #再调用向量化处理过的函数print(b)
(4)从存储身份证号码的数组中提取出生日期信息。
参考代码如下:
a = ["330281200409172215","522424200405202975","610528200409070018"]a = np.array(a)def fun3(x): #非连续函数returnx[6:14]fun_vec = np.vectorize(fun3) #先对fun3进行向量化处理b = fun_vec(a) #再调用向量化处理过的函数print(b)
(5)随机生成一个numpy数组a,返回其对应的二进制数(非连续函数)。
参考代码如下:
a = np.random.randint(-10, 10, 3)print(a)def fun4(x): #非连续函数returnbin(x)fun_vec = np.vectorize(fun4) #先对fun4进行向量化处理b = fun_vec(a) #再调用向量化处理过的函数print(b)
(6)随机生成2个numpy数组a和b,若a>b,返回a-b;否则返回b-a(非连续函数)。
参考代码如下:
a = np.random.randint(-10, 10, 3)b = np.random.randint(-10, 10, 3)print(a, b)def fun5(a, b): #非连续函数if a > b:return a- belse:return b- afun_vec = np.vectorize(fun5) #先对fun5进行向量化处理c = fun_vec(a, b) #再调用向量化处理过的函数print(c)
知识小贴士
vectorize()函数用来将函数向量化处理,以便可以批量处理numpy数组的每一个元素,其具体参数如下:
numpy.vectorize(pyfunc, otypes=None, doc=None,excluded=None, cache=False, signature=None)
pyfunc : python函数或方法。
otypes : 输出数据类型。必须将其指定为一个typecode字符串或一个数据类型说明符列表。每个输出应该有一个数据类型说明符。
doc : 函数的docstring。如果为None,则docstring将是pyfunc.__doc__。
excluded : 表示函数不会向量化的位置或关键字参数的字符串或整数集。这些将直接传递给未经修改的pyfunc。
cache :如果为True,则缓存第一个函数调用,该函数调用确定未提供otype的输出数。
signature : 广义通用函数签名,例如,(m,n),(n)->(m)用于矢量化矩阵 - 向量乘法。如果提供的话,pyfunc将调用(并期望返回)具有由相应核心维度的大小给出的形状的数组。默认情况下,pyfunc假定将标量作为输入和输出。
函数返回值:向量化的数组。
需要本文源代码和word文稿的,可以加入“Python算法之旅”知识星球参与讨论和下载文件,“Python算法之旅”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注Python算法,感兴趣就一起来!
相关优秀文章:
