ufunc运算

ufunc是universal function的缩写,它是一种能对数组中每个元素进行操作的函数。Numpy内置的许多ufunc函数都是C语言实现的,计算速度非常快,简单看个例子:

[python] view plain copy
  1. >>> x = np.linspace(0,2*np.pi,10)  
  2. >>> y=np.sin(x)  
  3. >>> y  
  4. array([  0.00000000e+00,   6.42787610e-01,   9.84807753e-01,  
  5.          8.66025404e-01,   3.42020143e-01,  -3.42020143e-01,  
  6.         -8.66025404e-01,  -9.84807753e-01,  -6.42787610e-01,  
  7.         -2.44929360e-16])  
  8. >>>   
      上述代码中先用linspace( )产生一个从0到2*PI的等差数组,然后将其传给np.sin( )计算每个元素的正弦值。函数计算完成后,返回一个计算结果的数组。如果通过out参数指定计算结果的保存位置,则计算结果将保存在out参数中,如:

[python] view plain copy
  1. >>> np.sin(x, out =y)  
  2. array([  0.00000000e+00,   6.42787610e-01,   9.84807753e-01,  
  3.          8.66025404e-01,   3.42020143e-01,  -3.42020143e-01,  
  4.         -8.66025404e-01,  -9.84807753e-01,  -6.42787610e-01,  
  5.         -2.44929360e-16])  
  6. >>> y  
  7. array([  0.00000000e+00,   6.42787610e-01,   9.84807753e-01,  
  8.          8.66025404e-01,   3.42020143e-01,  -3.42020143e-01,  
  9.         -8.66025404e-01,  -9.84807753e-01,  -6.42787610e-01,  
  10.         -2.44929360e-16])  
  11. >>>   
        对于计算单个元素,则建议采用Math库里对应的函数,np.sin( )对应math.sin( ),因为对于np.sin( )为了实现数组计算,底层做了很多复杂的处理,因此对于单个元素,math库里的函数计算速度快得多;而对于数组元素,则采用numpy库里的函数计算
        在读取计算结果时,通过下标获取数组元素的类型为Numpy中定义的类型,将其转换为python的标准类型需耗时间。针对此问题,可以采用数组提供的item( )方法,用来获取数组中单个元素,并直接返回标准的python数据类型,如:

[python] view plain copy
  1. >>> a = np.arange(6.0).reshape(2,3)  
  2. >>> a.item(1,2)  #与a[1,2]类似  
  3. 5.0  
  4. >>> type(a.item(1,2))  
  5. <class 'float'>  
  6. >>> type(a[1,2])  
  7. <class 'numpy.float64'>  
  8. >>>   
          一、数组的四则运算



           二、比较和布尔运算

         使用“==”、“>”等比较运算符比较两个数组,将返回一个布尔数组,它的每个元素的值是两个数组对应元素比较的结果,如:

[python] view plain copy
  1. >>> np.array([1,2,3])==np.array([3,2,1])  
  2. array([False,  TrueFalse], dtype=bool)  
  3. >>> np.array([1,2,3])<np.array([3,2,1])  
  4. array([ TrueFalseFalse], dtype=bool)  
  5. >>>   
       

 由于Python的布尔运算使用and,or和Not等关键字,无法被重载,因此数组的布尔运算智能通过ufunc对应的函数来操作,这些函数以"logical_"开头,如下:


       以“bitwise_"开头的函数是比特运算函数,包括bitwise_and、bitwise_not、bitwise_or和bitwise_xor等,也可以使用&、~、|、^等操作符来计算。对于布尔数组来说,位运算和布尔运算的结果相同,但是位运算符的优先级高于比较运算符。

        自定义ufunc函数

        通过Numpy提供的标准ufunc函数可以满足大多要求,但有些特殊情况需要自定义函数来实现。这时,可以采用python来实现,然后使用frompyfunc( )函数将一个计算单个元素的函数转换为ufunc函数。例如,用一个分段函数来描述三角波,它的样子如图所示:


Python函数定义如下:

[python] view plain copy
  1. def triangle_wave(x,c,c0,hc):  
  2.     x = x - int(x)   #周期为1,取小数部分计算  
  3.     if x>=c:  
  4.         r = 0.0  
  5.     elif x<c0:  
  6.         r = x/c0*hc  
  7.     else:  
  8.         r = (c-x)/(c-c0)*hc  
  9.     return r  
          1)通过列表推导计算

         先使用列表推导计算一个列表,然后用array( )转换为数组,这种方法每次都要使用列表推导,而且对于多维数组,比较复杂,计算如下:

[python] view plain copy
  1. x = np.linspace(0,2,1000)  
  2. y1 = np.array([triangle_wave(t,0.6,0.4,1.0for t in x])  
          2)fromnpyfunc( )函数计算

         通过frompyfunc( )可以将计算单个值的函数转换为一个能对数组中每个元素计算的ufunc函数。frompyfunc( )的调用格式为:

[python] view plain copy
  1. frompyfunc(func,nin,nout)  
 其中,ufunc是计算单个元素的函数,nin是输入参数的个数,nout是func返回值的个数。如:

[python] view plain copy
  1. triangle_wave_ufunc = np.frompyfunc(triangle_wave,4,1)  
  2. y2 = triangle_wave_ufunc(x,0.6,0.4,1.0)  
代码简洁高效。值得注意: triangle_wave_ufunc( )所返回数组的元素类型是object,因此还需要调用数组的astype()方法将其转换为双精度浮点数组



           3)vectorize( )函数计算

        使用vectorize( )可以实现和frompyfunc( )类似的功能,但他可以通过otypes参数指定返回数组的元素类型。otypes参数可以是一个表示元素类型的字符串,也可以是一个类型列表,使用列表可以描述多个返回数组的元素类型,如将上面的代码改成vectorize( ),则为:

[python] view plain copy
  1. triangle_wave_vec = np.vectorize(triangle_wave, otypes[np.float])  
  2. y3 = triangle_wave_vec(x,0.6,0.4,1.0)  
       到这里,ufunc函数的强大自不必言,如果将其与图像处理、信号处理等数组形式的应用结合起来,可以发挥强大作用。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值