整体操作numpy数组的方法
共 5403字,需浏览 11分钟
·
2022-01-05 12:28
说在前面
numpy数组支持与标量的加、减、乘、除和幂等算术运算,计算结果为一个新数组,其元素为标量与原数组每个元素进行计算的结果。演示代码如下:
2. numpy 数学函数和算术函数>> a = np.arange(8)
#修改数组形状为2行4列 >> a.shape = (2, 4)
>> a
array([[0, 1, 2, 3],
[4, 5, 6,7]])
>> a + 2
array([[2, 3, 4, 5],
[6, 7, 8,9]])
>> a - 2
array([[-2, -1, 0, 1],
[ 2, 3, 4, 5]])
>> a * 2
array([[ 0, 2, 4, 6],
[ 8, 10,12, 14]])
>> a / 2
array([[0. , 0.5, 1. , 1.5],
[2. ,2.5, 3. , 3.5]])
>> a // 2
array([[0, 0, 1, 1],
[2, 2, 3,3]], dtype=int32)
>> a % 2
array([[0, 1, 0, 1],
[0, 1, 0,1]], dtype=int32)
#分别计算0**2,1**2,2**2,…,7**2 >> a ** 2
array([[ 0, 1, 4, 9],
[16, 25,36, 49]], dtype=int32)
#分别计算2**0,2**1,2**2,…,2**7 >> 2 ** a
array([[ 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数组进行算术运算,得到一个新数组,其元素的值为原来的两个数组中对应位置上元素进行运算的结果。演示代码如下:
1,3,5,7,9],[2,4,6,8,10]]) > a =np.array([[
> a
array([[ 1, 3, 5, 7, 9],
[ 2, 4, 6, 8,10]])
1,2,3,4,5],[10,9,8,7,6]]) > b = np.array([[
> b
array([[ 1, 2, 3, 4, 5],
[10, 9, 8, 7, 6]])
> a + b
array([[ 2, 5, 8,11, 14],
[12, 13, 14, 15, 16]])
> a - b
array([[ 0, 1, 2, 3, 4],
[-8, -5, -2, 1, 4]])
> a * b
array([[ 1, 6, 15, 28, 45],
[20, 36, 48, 56, 60]])
> a / b
array([[1. , 1.5 , 1.66666667, 1.75 , 1.8 ],
[0.2 , 0.44444444, 0.75 , 1.14285714, 1.66666667]])
> a % b
array([[0, 1, 2, 3, 4],
[2, 4, 6, 1, 4]], dtype=int32)
> a ** b
array([[ 1, 9, 125, 2401, 59049],
[ 1024, 262144, 1679616, 2097152, 1000000]],dtype=int32)
(2)numpy数组广播机制。
当运算中的 2个数组的形状不同时,numpy将自动触发广播机制。演示代码如下:
0, 0,0],[10,10,10],[20,20,20],[30,30,30]]) > a = np.array([[
1,2,3]) > b = np.array([
> a + b
array([[ 1, 2, 3],
[11, 12,13],
[21, 22,23],
[31, 32,33]])
图1-2展示了数组b如何通过广播来与数组a兼容。
图1-2
注意:若想要两个数组通过广播机制来实现兼容,则其中某个数组的维度必须为1(即只有1行或1列);若条件不满足,则抛出异常。演示代码如下:
1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]) > a =np.array([[
1],[2],[3],[4]]) > b = np.array([[
> a + b
array([[ 2, 3, 4, 5],
[ 7, 8, 9,10],
[12, 13,14, 15],
[17, 18,19, 20]])
1, 2],[3, 4]]) > c = np.array([[
> a + c
Traceback (most recent call last):
File"
" , line 1, in <module>a + c
ValueError: operands could not be broadcast togetherwith shapes (4,4) (2,2)
(3)连接数组。
concatenate()函数用于沿指定轴连接相同维度的两个或多个数组,函数格式如下:
np. concatenate((a1, a2, ...), axis=0)
其中a1, a2, ...表示多个相同维度的数组;axis表示沿着它连接数组的轴,值为0时增加行数,值为1时增加列数。演示代码如下:
1,2],[3,4],[5,6]]) > a = np.array([[
> a
array([[1, 2],
[3, 4],
[5, 6]])
4, 5],[6,7]]) > b = np.array([[
> b
array([[4, 5],
[6, 7]])
0) #沿轴0连接两个数组,要确保列数相同 > np.concatenate((a,b),axis=
array([[1, 2],
[3, 4],
[5, 6],
[4, 5],
[6, 7]])
1],[2],[3]]) > c = np.array([[
> c
array([[1],
[2],
[3]])
1) #沿轴1连接两个数组,要确保行数相同 > np.concatenate((a,c),axis=
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)
>> a
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9,10])
#提供1个参数,只返回满足条件的索引数组 >> np.where(a % 2 == 1)
(array([0, 2, 4, 6, 8], dtype=int64),)
#使用索引重构原数组 >> a[np.where(a % 2 ==1)]
array([1, 3, 5, 7, 9])
#提供3个参数,满足条件取值1,否则取值0 >> np.where(a % 2 == 1, 1,0)
array([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]])
>> a
array([[1, 2, 3, 4,5],
[2, 3, 4, 5, 6],
[3, 4, 5, 6, 7],
[4, 5, 6, 7, 8]])
#提供1个参数,只返回满足条件的索引数组 >> i =np.where((a>4) & (a<7))
#因为a是二维数组,故i为由索引数组构成的元组,分别存储了满足条件的数组元素的行索引和列索引 >> 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])
#提供3个参数,满足条件取值1,否则取值0 >> np.where(a % 2 == 1, 1, 0)
array([[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0]])
#提供3个参数,奇数翻倍,偶数减半 >> np.where(a % 2 == 1, a*2, a//2)
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)) // 2
print(b)
#方法三:布尔索引
a[a<0] = 0
print(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+5
b = 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-3
else:
y = 2*x+6
return y
fun_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- b
else:
return b- a
fun_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算法,感兴趣就一起来!
相关优秀文章: