python对数组进行分段函数的映射

551 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路 应用场景:对list或者array中的每一个元素进行判断在函数的哪个区间,并进行函数计算输出。
方法:map()函数,np.select(),np.piecewise(),np.where()
代码:

import numpy as np

def func1(a):
    if(a>=0 and a<1):
        return  a**2
    if(a>=1 and a<2):
        return a**2-1
    if(a>=2 and a<3):
        return a**2-2*a+1

def piecewise():
     t=np.array([i for i in np.arange(0,3,0.5)])     #与matlab不同,python中不会将最后一个数计入数组中
     y1=np.where((t>=0)&(t<1),t**2,np.where(t<2,t**2-1,np.where(t<3,t**2-2*t+1,False)))
     y2=np.select([(t>=0)&(t<1),t<2,t<3],[t**2,t**2-1,t**2-2*t+1])
     y3=np.piecewise(t,[t<3, t<2, (t>=0)&(t<1)],[lambda t:t**2-2*t+1,lambda x: x**2-1,lambda x:x**2])   #以上对切片的逻辑运算(且)都需要变成位运算&而不能用and不然会报错
     y4=np.array(list(map(func1,t)))  #使用map对迭代器有元素操作时,func不带参数
     ufunc1=np.frompyfunc(func1,1,1)
     y5=ufunc1(t)
     print(t)
     print(y1)
     print(y2)
     print(y3)
     print(y4)
     print(y5)

piecewise()

结果如下:

[0.  0.5 1.  1.5 2.  2.5]
[0.   0.25 0.   1.25 1.   2.25]
[0.   0.25 0.   1.25 1.   2.25]
[0.   0.25 0.   1.25 1.   2.25]
[0.   0.25 0.   1.25 1.   2.25]
[0.0 0.25 0.0 1.25 1.0 2.25]

各方法不同:

  1. np.where()属于通过不断的嵌套if和np.where语句确定每个子区间,每个子区间内执行相应的函数;

  2. np.select()对前一方法进行了简化,给出了优先级从高到低的条件列表从而隐式的确定了区间,再给出函数即可。

  3. np.piecewise()和np.select()类似,但条件列表的优先级顺序是从低到高,同时 np.select()中函数部分不用写函数只要表达式即可,而np.piecewise需要一个确切的函数。

  4. 显式函数方法需要先构建分段函数,再调用map()函数进行映射,或者使用np.frompyfun()将函数表达式转化成类似内联函数的形式。