ufunc是对ndarray执行运算的函数,用矢量化运算的方法极大的提高运算效率。
numpy内置的ufunc
1个输入值的内置ufunc
函数 | 说明 |
---|---|
abs | 绝对值 |
sqrt | 比a**0.5快 |
exp | |
log,log10,log2 | |
sign | |
ceil | 向上取整 |
floor | 向下取整 |
rint | 四舍五入 |
isnan | |
isfinite | |
isinf | |
sin,sinh,cos,cosh,tan,tanh | |
arcsin,arccos,arctan,arcsinh,arccosh,arctanh |
注:
- 基本都可以传入
out=x
制定输出到哪个变量
2个输入值的内置ufunc
符号运算
a+b
a-b
a*b
a/b
a//b #商
a%b #余数
#1. a,b是同样shape的ndarray
#2. b可以是数字
#3. b可以是1个元素的ndarray,如np.array([2])
b=a.T#转置
np.linalg.inv(a)#取逆
布尔运算
- 生成bool
x==y x!=y x<y x<=y x>y x>=y
- bool运算:
& #与 ~ #非 | #或 ^ #异或
注意:
- 实际上
&~|^
是按位运算符,因为与array.dtype=bool的情况下,与逻辑运算效果完全相同,所以可以这么用 - and 和 or 等逻辑运算符不能直接对array使用,因为他们只能用于True/False
- 非bool方式是取反,运算规则与C语言完全相同(有些编程技巧)
- dtype=np.int32
~0=-1
- dtype=np.int8
~0=255
- dtype=np.int32
np.any np.all
- np.any(a==b) and np.all(a>b)
其它运算符
函数 | 说明 |
---|---|
maximum | a,b对应每项的最大值 |
minimum | a,b对应每项最小值 |
自己构建ufunc
ufunc函数可以矢量化运算,提高运算效率,增加代码可读性
准备函数和数据:
import numpy as np
def func(x, a=1, b=0):
return int(x) + int(a) - int(b)
ufunc = np.frompyfunc(func, nin=3, nout=1)
# nin 和 nout 是 ufunc 输入值的数量 和 输出值的数量
# 如果 nin 设定为2,那么x和a是矢量,b就用默认值
ufunc(np.linspace(1, 5, 10), np.array([[3], [2]]), 2)
输出有多个,一样的
import numpy as np
# 构建函数
def oct_fun(x, a=1, b=0):
return int(x) + int(a) - int(b), x + a + b
oct_ufun = np.frompyfunc(oct_fun, 3, 2)
oct_ufun(np.linspace(1, 5, 10), np.array([[3], [2]]), 2)
(测试发现,并不是并行运行的)
广播计算
def func1(x,y,c=0):
return (x-1)**2+(y-1)**2+c
import numpy as np
func2=np.frompyfunc(func1,2,1)
x=np.linspace(0,2,5)
y=np.linspace(0,2,10).reshape(10,-1)
func1(x,y)
意思是,当shape不一致的array进行ufunc运算时,自动用repeat补齐
reduce()
只对两个输入、一个输出的ufunc对象有效
np.vectorize
前面的frompyfunc构建的函数,特点是广播计算,每次输入的是 array 中的一个元素。
import numpy as np
def myfunc(a, b):
"Return a-b if a>b, otherwise return a+b"
if a > b:
return a - b
else:
return a + b
vfunc = np.vectorize(myfunc)
# 入参可以是list,数字,不同shape的array,规则与广播计算完全一样
vfunc([1, 2, 3, 4], 2)
vfunc([1, 2, 3, 4], [1, 2, 3, 4])
参数
excluded 可以让参数不矢量化,而是直接进入函数
def mypolyval(p, x):
return sum(p) + x
vpolyval = np.vectorize(mypolyval, excluded=['p'])
vpolyval(p=[1, 2, 3], x=[0, 1])
# 也可以用这个命令,达成同样的效果
vpolyval.excluded.add(0)