ufunc是universal function的缩写,它是一种能对数组的每个元素进行运算的函数。
NumPy提供了许多ufunc函数,本篇博文主要介绍一些常见的ufunc
一、四则运算
表达式 | 对应的ufunc函数 |
---|---|
y = x1 + x2 | add(x1, x2[,y]) |
y = x1 - x2 | subtract(x1, x2[,y]) |
y = x1 * x2 | multiply(x1, x2[,y]) |
y = x1 / x2 | divide(x1, x2[,y]),如果两个数组的元素为整数,则用整数除法 |
y = x1 / x2 | true_divide(x1, x2[,y]),总是返回精确的商 |
y = x1 / x2 | floor_divide(x1, x2[,y]),总是对返回值取整 |
y = -x | negative(x1 [,y]) |
y = x1**x2 | power(x1, x2[,y]) |
y = x1 % x2 | remainder(x1, x2[,y]),mod(x1, x2[,y]) |
# add
a = np.arange(0, 4)
b = np.arange(1, 5)
print(np.add(a, b))
# multiply
a = np.arange(0, 4)
b = np.arange(1, 5)
print(np.multiply(a, b))
二、比较运算和布尔运算
表达式 | 对应的ufunc函数 |
---|---|
y = x1 == x2 | equal(x1,x2[,y] |
y = x1 != x2 | not_equal(x1,x2[,y]) |
y = x1 < x2 | less(x1,x2[,y]) |
y = x1 <= x2 | less_equal(x1,x2[,y]) |
y = x1 > x2 | greater(x1,x2[,y]) |
y = x1 >= x2 | greater_equal(x1,x2[,y]) |
np.array([1, 2, 3]) < np.array([3, 2, 1])
由于Python中的布尔运算使用and、or和not关键字,它们无法被重载,因此数组的布尔运算只能通过相应地ufunc函数进行。
可以通过用tab补全logical_
查找
a = np.arange(5)
b = np.arange(4, -1, -1)
print(a == b)
print(a > b)
print(np.logical_or(a == b, a > b)) # 和 a>=b 相同
以bitwise_
开头的是位运算函数,包括bitwise_and
、bitwise_not
、bitwise_or
和bitwise_xor
等。也可以使用&
、~
、|
和^
等操作符进行计算
a = np.arange(5)
b = np.arange(4, -1, -1)
(a == b) | (a > b)
a = np.arange(5)
b = np.arange(4, -1, -1)
~ np.arange(5)
三、广播
当使用ufunc函数对两个数组进行计算时,ufunc函数会对这两个数组的对应元素进行计算,因此它要求这两个数组的形状相同。如果形状不相同,会进行如下广播处理:
(1)让所有输入数组都向其中维数最多的数组看齐,shape属性中不足的部分都通过在前面加1补齐。
(2)输出数组的shape属性是输入数组的shape属性的各个轴上的最大值
(3)如果输入数组的某个轴的长度为1或与输出数组的对应轴的长度相同,这个数组就能用来计算,否则出错
(4)当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值。
如我们对两个维度不同的数组进行相加
a = np.arange(0, 60, 10).reshape(-1, 1)
print(a)
print('')
b = np.arange(0, 5)
print(b)
print('')
c = a + b
print(c)
再分别看下数组a、b和c的shape
print(a.shape)
print('-'*20)
print(b.shape)
print('-'*20)
print(c.shape)
理论上来说两个维度不同的数组,是不能直接相加的。但是通过广播完成了加法运算:
首先根据(1),b的shape向a看齐,在b的shape属性前加1,即b的shape补齐为(1,5)
此时两个数组的shape已经分别为(6, 1)和(1, 5)
然后根据(2),b的0轴长度小于a的0轴,为了能相加,b的第0轴的长度扩展为6,即
其次由于a的第1轴长度为1,而b的第1轴长度为5,将a的第1轴的长度扩展为5,即
最后相加即为所得。
四、ufunc的方法
ufunc函数对象本身还有一些方法函数
- reduce()
reduce()
方法和Python内置reduce()
函数类似
r1 = np.add.reduce([1, 2, 3]) # 1 + 2 + 3
r2 = np.add.reduce([[1, 2, 3], [4, 5, 6]], axis=1) # (1+2+3),(4+5+6)
print(r1)
print('-'*20)
print(r2)
- accumulate()
accumulate()
方法和reduce()
方法类似,只是它返回的数组和输入数组的形状相同
a1 = np.add.accumulate([1, 2, 3])
a2 = np.add.accumulate([[1, 2, 3], [4, 5, 6]], axis=1)
print(a1)
print('-'*20)
print(a2)
- reduceat()
reduceat()
方法计算多组reduce()
的结果,通过indices
参数指定一系列的起始和终止位置
a = np.array([1, 2, 3, 4])
result = np.add.reduceat(a, indices=[0, 1, 0, 2, 0, 3, 0])
print(result)
其具体计算过程为:
1:a[0] = 1
2:a[1] = 2
3:a[0] + a[1] = 3
3:a[2] = 3
6:a[0] + a[1] + a[2] = 6
4:a[3] = 4
10:a[0] + a[1] + a[2] + a[3] = 10
lz个人理解为:每次到indices值为0的时候,将前面索引非0的值进行求和
- outer()
outer()
看了就知道是什么意思
a = np.multiply.outer([1, 2, 3, 4, 5], [2, 3, 4])
print(a)