8.8.ufunc函数
import numpy as np
np.set_printoptions(threshold=40)
Linux 5.4.0-74-generic
Python 3.9.5 @ GCC 7.3.0
Latest build date 2021.06.16
numpy version: 1.20.3
通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。可以将其看做简单函数(接受一个或多个标量值,并产生一个或多个标量值)的矢量化包装器。
-
一元(unary)ufunc:接受1个数组的输入。
-
二元(binary)ufunc:接受2个数组的输入。
四则运算
a = np.arange(1, 6)
b = np.arange(5, 10)
# 表达式形式
a + a
a - a
a * a # 元素相乘
a / a
b // a # 取整除法
b % a # 取模
# ufunc函数形式
np.add(a, a)
np.subtract(a, a)
np.multiply(a, a) # 元素相乘
## 在python3 divide、true_divide没有差别
np.true_divide(b, a)
np.divide(b, a)
## 相当于先调用divide函数 再调用floor函数
np.floor_divide(b, a) # 取整除法
np.mod(b, a) # 元素级求模
array([0, 0, 1, 0, 4])
比较运算
a = np.arange(20).reshape(2,10)
b = np.arange(10,30).reshape(2,10)
# 表达式形式
a == b
a != b
a < b
a <= b
a > b
a >= b
# ufunc函数形式
np.equal(a,b)
np.not_equal(a,b)
np.less(a,b)
np.less_equal(a,b)
np.greater(a,b)
np.greater_equal(a,b)
array([[False, False, False, False, False, False, False, False, False,
False],
[False, False, False, False, False, False, False, False, False,
False]])
逻辑运算
a = np.arange(20).reshape(2, 10)
b = np.arange(10, 30).reshape(2, 10)
# 与
np.logical_and(a, b)
# 或
np.logical_or(a, b)
# 非
np.logical_not(b)
# 异或
np.logical_xor(a, b)
# 任意一个元素
np.any(a)
# 全部元素
np.all(a)
False
位运算
a = np.arange(20).reshape(2, 10)
b = np.arange(10, 30).reshape(2, 10)
a & b
a | b
~a
a^b
# 按位与
np.bitwise_and(a, b)
# 按位或
np.bitwise_or(a, b)
# 按位取反
np.bitwise_not(a)
# 按位异或
np.bitwise_xor(a, b)
array([[10, 10, 14, 14, 10, 10, 22, 22, 26, 26],
[30, 30, 26, 26, 22, 22, 10, 10, 14, 14]])
自定义 ufunc 函数
可以通过frompyfunc()
将计算单个元素的函数转换成ufunc函数。调用格式为如下:
numpy.frompyfunc(func, nin, nout)
# func:计算单个元素的函数
# nin:func的输入参数的个数 The number of input
# nout:func返回值的个数 The number of output
def my_add(x, y):
z = x + y + 1
return z
myufunc = np.frompyfunc(my_add, 2, 1)
a = np.arange(5)
b = np.arange(5,10)
myufunc(a, b)
array([6, 8, 10, 12, 14], dtype=object)
也可以通过vectorize()
函数来实现frompyfunc()
的功能。
np.vectorize(func, otypes='', doc=None, excluded=None)。
# func:计算单个元素的函数
# otypes:可以是一个表示结果数组元素类型的字符串,也可以是一个类型列表。如果使用类型列表,可以描述多个返回数组的元素类型
# doc:函数的描述字符串。若未给定,则使用func.__doc__
# excluded:指定func中哪些参数未被向量化。你可以指定一个字符串和整数的集合,其中字符串代表关键字参数,整数代表位置参数。
a = np.arange(5)
b = np.arange(5,10)
def my_add(x, num):
z = x + num
return z
myufunc = np.vectorize(my_add, doc="每一个元素加上一个指定的数")
print(myufunc.__doc__)
myufunc(a, 1)
每一个元素加上一个指定的数
array([1, 2, 3, 4, 5])
def my_add(x, y, list_num):
z = x + y
for i in list_num:
z = z + i
return z
myufunc = np.vectorize(my_add, excluded=[2])
myufunc(a, b, [1, 2, 3]) # list_num 作为一个list,而不是向量化成一个个元素
array([11, 13, 15, 17, 19])
def my_add(x, num):
z = x + num
return z, z
myufunc = np.vectorize(my_add, otypes=[np.float, int])
myufunc(a, 1)
<ipython-input-1-4753d7c47f71>:5: DeprecationWarning: `np.float` is a
deprecated alias for the builtin `float`. To silence this warning, use
`float` by itself. Doing this will not modify any behavior and is
safe. If you specifically wanted the numpy scalar type, use
`np.float64` here.
Deprecated in NumPy 1.20; for more details and guidance:
https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
myufunc = np.vectorize(my_add, otypes=[np.float, int])
(array([1., 2., 3., 4., 5.]), array([1, 2, 3, 4, 5]))
ufunc 对象的方法
ufunc函数对象本身还有一些方法。
这些方法只对于两个输入、一个输出的ufunc函数函数有效。对于其他的ufunc函数对象调用这些方法时,会抛出ValueError
异常。
ufunc.reduce()
ufunc.reduce
方法:类似于Python的reduce
函数,它==沿着==axis
参数指定的轴,对数组进行操作。经过一次reduce,结果数组的维度降低一维。
假设<op>
是一个ufunc函数,ufunc.reduce
用法如下:
<op>.reduce(array,axis=0,dtype=None)
a = np.arange(20).reshape(5, 4)
print(a)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
np.add.reduce(a, axis=1) # 沿着 列方向
array([ 6, 22, 38, 54, 70])
np.add.reduce(a, axis=0) # 沿着 行方向
array([40, 45, 50, 55])
相当于将
a = np.arange(20).reshape(5, 4)
print(a)
def fun(a,b):
z = a + b + 1
return z
fun2 = np.frompyfunc(fun, 2, 1)
fun2.reduce(a, axis=1)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
array([9, 25, 41, 57, 73], dtype=object)
ufunc.accumulate()
ufunc.accumulate
方法:它类似于reduce()的计算过程,但是它会保存所有的中间计算结果,从而使得返回数组的形状和输入数组的形状相同:
a = np.arange(20).reshape(5, 4)
print(a)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]]
np.add.accumulate(a, axis=1)
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38],
[12, 25, 39, 54],
[16, 33, 51, 70]])
ufunc.outer()
ufunc.outer
方法:相当于将
一维数组和一维数组的outer操作为二维数组
a = np.arange(1, 6)
b = np.arange(1, 5)
np.add.outer(a, b)
array([[2, 3, 4, 5],
[3, 4, 5, 6],
[4, 5, 6, 7],
[5, 6, 7, 8],
[6, 7, 8, 9]])
多维数组的outer拆分成各自的一维操作
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(1, 5)
np.add.outer(a, b)
array([[[ 2, 3, 4, 5],
[ 3, 4, 5, 6],
[ 4, 5, 6, 7]],
[[ 5, 6, 7, 8],
[ 6, 7, 8, 9],
[ 7, 8, 9, 10]]])
数学函数
下面是一元的数学函数:
-
abs/fabs
:计算整数、浮点数或者复数的绝对值。对于非复数值,可以使用更快的fabs -
sqrt
:计算平方根,相当于$a^{0.5}$ -
square
:计算平方,相当于$a^2$ -
exp
:计算指数$e^x$ -
log/log10/log2/log1p
:分别为$log_{e}(a), log_{10}(a), log_2(a), log_e(1+x)$ -
sign
:计算$sign(a)$ -
ceil
:计算各元素的ceiling值:大于等于该值的最小整数 -
floor
:计算个元素的floor值:小于等于该值的最大整数 -
rint
:将各元素四舍五入到最接近的整数,保留dtype
-
modf
:将数组的小数和整数部分以两个独立数组的形式返回 -
cos/cosh/sin/sinh/tan/tanh
:普通和双曲型三角函数 -
arccos/arcsosh/arcsin/arcsinh/arctan/arctanh
:反三角函数 -
isnan
:返回一个布尔数组,该数组指示那些是NaN
-
isfinite/isinf
:返回一个布尔数组,该数组指示哪些是有限的/无限数
统计函数
方法 | 说明 |
---|---|
sum |
对数组中全部或某轴向的元素求和。零长度的数组的sum为0 |
mean |
算术平均数。零长度的数组的mean为NaN |
std 、var |
分别为标准差和方差,自由度可调(默认为n) |
min 、max |
最大值和最小值 |
argmin 、argmax |
分别为最大和最小元素的索引 |
cumsum |
所有元素的累计和 |
cumprod |
所有元素的累计积 |
以上函数有一些共同的参数:(a, axis=None, dtype=None, out=None)
-
axis
:None
、整数、整数元组。按顺序对axis
指定的轴进行计算。例如,指定所有的轴,最后则输出一个标量。 -
out
:ndarray。将结果输出到该数组。它必须有与预期输出形状相同,但输出类型必要时将强制转换值。
集合运算
方法 | 说明 |
---|---|
unique(x) |
计算x中的唯一元素,并返回有序结果 |
intersect1d(x, y) |
计算X和y中的公共元素,并返回有序结果 |
union1d(x, y) |
计算X和y的并集,并返回有序结果 |
in1d(x,y) |
得到一个表示“X的元素是否包含于y”的布尔型数组 |
setdiff1d(x, y) |
集合的差,即元素在x中且不在y中 |
setxor1d(x, y) |
集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素 |
a = np.arange(0, 5)
b = np.arange(3, 8)
print(np.unique(a))
print(np.intersect1d(a, b))
print(np.union1d(a, b))
print(np.in1d(a, b))
print(np.setdiff1d(a, b))
print(np.setxor1d(a, b))
[0 1 2 3 4]
[3 4]
[0 1 2 3 4 5 6 7]
[False False False True True]
[0 1 2]
[0 1 2 5 6 7]