universal function, 或 ufunc, 是用来在ndarray中实现element-wise操作的。
可以认为这个ufunc可以把一些简单的函数做快速的向量化封装,输入是一个以上的标量,输出也是一个以上的标量。
很多ufuncs都是点对点的变换,像sqrt或exp:
import numpy as np
arr = np.arange(10)
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.sqrt(arr)
array([ 0. , 1. , 1.41421356, 1.73205081, 2. , 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
np.exp(arr)
array([ 1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01, 5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03, 2.98095799e+03, 8.10308393e+03])
这些函数叫做一元通用函数(unary ufuncs)。其他一些函数,比如add或maximum,需要两个数组(binary ufuncs),并返回一个数组作为结果:
x = np.random.randn(8)
y = np.random.randn(8)
x
array([ 0.18373557, -1.82728347, -0.11149882, -1.34286776, -1.09016986, 1.63308 , 1.05205535, -0.32746706])
y
array([-0.42410809, 1.89603273, -1.13649816, -0.98559379, -0.16827718, 0.52828569, 1.57543351, 1.50045399])
np.maximum(x, y)
array([ 0.18373557, 1.89603273, -0.11149882, -0.98559379, -0.16827718, 1.63308 , 1.57543351, 1.50045399])
这里mamimum点对点的比较x和y中的元素。
尽管不常见,但ufunc也能返回多个数组。例如modf,这是一个向量版的divmod(python内建函数),modf会返回小数部分和整数部分:
本函数是实现a除以b,然后返回商与余数的元组。如果两个参数a,b都是整数,那么会采用整数除法,结果相当于(a//b, a % b)。如果a或b是浮点数,相当于(math.floor(a/b), a%b)。
arr = np.random.randn(7) * 5
arr
array([ 1.51538382, -0.75054846, 0.02863286, 8.74026861, -3.44529124, -9.18401768, -0.68469611])
remainder, whole_part = np.modf(arr)
remainder
array([ 0.51538382, -0.75054846, 0.02863286, 0.74026861, -0.44529124, -0.18401768, -0.68469611])
whole_part
array([ 1., -0., 0., 8., -3., -9., -0.])
ufunc能接受一个可选参数作为输出,这样可以直接更改原有的数组:
arr
array([ 1.51538382, -0.75054846, 0.02863286, 8.74026861, -3.44529124, -9.18401768, -0.68469611])
np.sqrt(arr) # 没有改变原有的arr
/Users/xu/anaconda/envs/py35/lib/python3.5/site-packages/ipykernel/__main__.py:1: RuntimeWarning: invalid value encountered in sqrt if __name__ == '__main__':
array([ 1.23100927, nan, 0.16921248, 2.95639453, nan, nan, nan])
np.sqrt(arr, arr) # 改变了原有的arr
/Users/xu/anaconda/envs/py35/lib/python3.5/site-packages/ipykernel/__main__.py:1: RuntimeWarning: invalid value encountered in sqrt if __name__ == '__main__':
array([ 1.23100927, nan, 0.16921248, 2.95639453, nan, nan, nan])
arr
array([ 1.23100927, nan, 0.16921248, 2.95639453, nan, nan, nan])
一些一元通用函数:
![](../MarkdownPhotos/chp04/屏幕快照 2017-10-25 下午1.19.41.png)
一些二元通用函数: ![](../MarkdownPhotos/chp04/屏幕快照 2017-10-25 下午1.21.08.png)
![](../MarkdownPhotos/chp04/屏幕快照 2017-10-25 下午1.21.42.png)