numpy的ufunc

介绍点高级的东西,numpy中的ufunc。

ufunc(universal function)能够作用于narray对象上的元素级函数,这些函数在对narray对象进行运算的速度比使用循环或者列表推导式要快很多。

numpy中的ufunc函数:



python 中的逻辑运算and、or、not 在numpy中均以以logical_开头。

ufunc方法
ufunc函数对象本身还有一些方法函数,这些方法只对两个输入、一个输出的ufunc 函数有效

(1) reduce()沿着指定轴对数组进行操作,相当于将相应的操作放到该轴元素之间。

In [111]: arr = np.arange(10)
In [112]: arr.add.reduce(45)
In [113]: np.add.reduce(45)
Out[113]: 45
In [114]: arr.sum()
Out[114]: 45
In [115]: arr1 = np.arange(12).reshape(3,4)
In [116]: arr1
Out[116]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [117]: np.add.reduce(arr1,axis=1)
Out[117]: array([ 6, 22, 38])
In [118]: np.add.reduce(arr1,axis=0)
Out[118]: array([12, 15, 18, 21])
In [119]: arr2 = np.random.rand(5,5)
In [120]: arr2
Out[120]: 
array([[0.58105936, 0.11015212, 0.57964562, 0.26717349, 0.37098113],
       [0.7986871 , 0.43831348, 0.23055509, 0.58390981, 0.26887167],
       [0.09343173, 0.75975338, 0.10638202, 0.09400437, 0.36757053],
       [0.31254715, 0.04461316, 0.18108053, 0.50666021, 0.85490671],
       [0.62270897, 0.89847847, 0.02525792, 0.21699692, 0.4513596 ]])

In [122]: arr2[::2].sort(1)
In [123]: arr2
Out[123]: 
array([[0.11015212, 0.26717349, 0.37098113, 0.57964562, 0.58105936],
       [0.7986871 , 0.43831348, 0.23055509, 0.58390981, 0.26887167],
       [0.09343173, 0.09400437, 0.10638202, 0.36757053, 0.75975338],
       [0.31254715, 0.04461316, 0.18108053, 0.50666021, 0.85490671],
       [0.02525792, 0.21699692, 0.4513596 , 0.62270897, 0.89847847]])
In [127]: arr2[:,:-1] < arr2[:,1:]
Out[127]: 
array([[ True,  True,  True,  True],
       [False, False,  True, False],
       [ True,  True,  True,  True],
       [False,  True,  True,  True],
       [ True,  True,  True,  True]])
In [128]: np.logical_and.reduce( arr2[:,:-1] < arr2[:,1:],axis=1)  # 利用 np.logical_and 判断各行是否有序
Out[128]: array([ True, False,  True, False,  True])

(2) accumulate()和reduce()的关系就想cumsum 和sum 的关系,区别时是前者会保留中间结果:

In [130]: arr = np.arange(15).reshape((3, 5))
In [131]: np.add.accumulate(arr)
Out[131]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  7,  9, 11, 13],
       [15, 18, 21, 24, 27]], dtype=int32)

(3) reduceat()方法用于部分reduce计算,通过indices参数指定一系列的起始和终止位置

In [136]: arr = np.arange(10)
In [137]: arr
Out[137]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [138]: np.add.reduceat(arr,[0,5,8])
Out[138]: array([10, 18, 17], dtype=int32)

(4) outer() 计算两个数组的交叉积

In [93]: arr = np.arange(3).repeat([1,2,2])
In [94]: arr
Out[94]: array([0, 1, 1, 2, 2])
In [95]: np.multiply.outer(arr,np.arange(5))   # arr的每一个元素与 np.arange(5) 所有元素相乘,组成一行
Out[95]: 
array([[0, 0, 0, 0, 0],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 2, 4, 6, 8],
       [0, 2, 4, 6, 8]])

In [97]: arr1 =  np.random.randn(3,4)
In [98]: arr1
Out[98]: 
array([[ 0.67543289,  0.36378869,  1.57406552, -0.82169794],
       [-0.3987699 ,  1.48855953,  2.18038345, -0.79266692],
       [ 0.73946519,  1.15944744, -0.38277991,  1.35506805]])
In [99]: arr2 =  np.random.randn(5)
In [100]: arr2
Out[100]: array([ 0.37966625, -0.27666319, -0.89753076,  1.76468965, -0.17493179])
In [101]: np.subtract.outer(arr1,arr2)    # shape (3,4,5)
Out[101]: 
array([[[ 0.29576664,  0.95209608,  1.57296365, -1.08925676,
          0.85036468],
        [-0.01587757,  0.64045188,  1.26131944, -1.40090097,
          0.53872048],
        [ 1.19439927,  1.85072872,  2.47159628, -0.19062413,.............
自定义 ufunc

除了numpy内置ufunc函数,用户也可以自定义的ufunc函数

1. 编写对单个数值计算的目的函数; 

def add_elements(x, y):
    return x + y

2. 利用np.frompyfunc(func, nin, nout)将其转换为ufunc函数

func:自己编写的目的函数,
nin: 参数个数
nout:返回值个数
In [105]: add_1 = np.frompyfunc(add_elements,2,1)
In [106]: add_1(np.arange(4),np.arange(4))
Out[106]: array([0, 2, 4, 6], dtype=object)
这里返回的结果是python的object类型,需要用astype()手动转换为目标类型。numpy.vectorize()也实现了和numpy.frompyfunc()一样的功能,但是它通过otypes指定返回值的类型,不用手动行转换。
In [107]: add_1 = np.vectorize(add_elements, otypes=[np.float64])
In [109]: add_1(np.arange(4),np.arange(4))
Out[109]: array([0., 2., 4., 6.])

自定义的ufunc在性能上不如内置的。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值