【numpy】ufunc



2017年07月05日    Author:Guofei

文章归类: 0x12_Pandas与numpy    文章编号: 1102

版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2017/07/05/ufunc.html


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

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)

您的支持将鼓励我继续创作!