1. 比较函数
函数名 | 基本功能 | 运算符等价形式 |
---|---|---|
greater(x1, x2) |
逐元素判断 x1 > x2 |
x1 > x2 |
greater_equal(x1, x2) |
逐元素判断 x1 >= x2 |
x1 >= x2 |
less(x1, x2) |
逐元素判断 x1 < x2 |
x1 < x2 |
less_equal(x1, x2) |
逐元素判断 x1 <= x2 |
x1 <= x2 |
equal(x1, x2) |
逐元素判断 x1 == x2 |
x1 == x2 |
not_equal(x1, x2) |
逐元素判断 x1 != x2 |
x1 != x2 |
示例 :
# 创建两个示例数组
arr1 = np.array([3, 5, 2, 8])
arr2 = np.array([4, 5, 0, 8])
# 使用函数和运算符进行逐元素比较
print("greater (arr1 > arr2):", np.greater(arr1, arr2)) # 等价于 arr1 > arr2
print("greater_equal (arr1 >= arr2):", np.greater_equal(arr1, arr2)) # 等价于 arr1 >= arr2
print("less (arr1 < arr2):", np.less(arr1, arr2)) # 等价于 arr1 < arr2
print("less_equal (arr1 <= arr2):", np.less_equal(arr1, arr2)) # 等价于 arr1 <= arr2
print("equal (arr1 == arr2):", np.equal(arr1, arr2)) # 等价于 arr1 == arr2
print("not_equal (arr1 != arr2):", np.not_equal(arr1, arr2)) # 等价于 arr1 != arr2
2. 逻辑运算函数
| 函数名 | 基本功能 | 运算符等价形式 |
| logical_and(x1, x2)
| 逐元素逻辑与操作 | x1 & x2
|
| logical_or(x1, x2)
| 逐元素逻辑或操作 | x1 \| x2
|
| logical_xor(x1, x2)
| 逐元素逻辑异或操作 | x1 ^ x2
|
| logical_not(x)
| 逐元素逻辑非操作 | ~x
|
示例 :
# 创建两个示例布尔数组
a = np.array([True, False, True, False])
b = np.array([True, True, False, False])
# 逻辑与:只有两个输入值都为 True 时,结果才为 True
result_and = np.logical_and(a, b)
print("np.logical_and(a, b):", result_and) # 输出: [ True False False False]
# 逻辑或:只要有一个输入值为 True,结果就为 True
result_or = np.logical_or(a, b)
print("np.logical_or(a, b):", result_or) # 输出: [ True True True False]
# 逻辑异或:两个输入值不同时结果为 True,相同时为 False
result_xor = np.logical_xor(a, b)
print("np.logical_xor(a, b):", result_xor) # 输出: [False True True False]
# 逻辑非:对单个输入值取反
result_not_a = np.logical_not(a)
print("np.logical_not(a):", result_not_a) # 输出: [False True False True]
不要使用 Python
关键字 and
和 or
来组合逻辑数组表达式,这些关键字将测试整个数组的真值(而不是您可能期望的逐元素):
A = np.array([True, False, True, False])
B = np.array([True, True, False, False])
result = A and B # 这会引发 ValueError,因为 Python 试图判断整个数组 A 的真值
# 输出:The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
可以改用按位运算符 &
和 |
:
# 逐元素逻辑与
logical_and_result = A & B # 输出:array([ True, False, False, False])
# 逐元素逻辑或
logical_or_result = A | B # 输出:array([ True, True, True, False])
3. 极值函数
函数名 | 基本功能 | 处理 NaN |
---|---|---|
fmax(x1, x2) |
逐元素比较两个数组,返回最大值 | 忽略 NaN |
fmin(x1, x2) |
逐元素比较两个数组,返回最小值 | 忽略 NaN |
maximum(x1, x2) |
逐元素比较两个数组,返回最大值 | 传播 NaN |
minimum(x1, x2) |
逐元素比较两个数组,返回最小值 | 传播 NaN |
处理 NaN
方式说明:
- 忽略
NaN
:如果比较的元素中有一个是NaN
,则返回非NaN
元素;如果两个都是NaN
,则返回第一个NaN
。 - 传播
NaN
:如果比较的元素中有任意一个是NaN
,则返回NaN
。
注意事项:
np.max
和np.min
不是通用函数,是聚合函数,即对输入数组的所有元素或沿指定轴进行聚合操作,返回一个或多个标量值。
Python
中的 max()
函数会在一维数组上查找最大值,但它使用较慢的序列接口,对于维度大于一的数组, max()
可能不会给出您期望的答案:
list=[1,2,3,4,5]
print(max(list)) # 5
np.maximum()
的 reduce
方法要快得多:
# 创建一个2维数组
arr_2d = np.random.randint(0, 100, size=(4, 5))
print(arr_2d)
# [[99 61 27 54 45]
# [49 67 52 3 33]
# [38 18 1 0 22]
# [39 30 60 61 19]]
# 查找整个数组的最大值
global_max = np.max(arr_2d)
print(global_max) # 99
# 沿 axis=0(列方向)求最大值 -> 结果为每列的最大值 (形状: (5,))
max_per_column = np.max(arr_2d, axis=0)
print(max_per_column) # [99 67 60 61 45]
# 沿axis=1(行方向)求最大值 -> 结果为每行的最大值 (形状: (4,))
max_per_row = np.max(arr_2d, axis=1)
print(max_per_row) # [99 67 38 61]
# 使用 reduce 方法实现同样效果
max_per_column_reduce = np.maximum.reduce(arr_2d, axis=0)
print(max_per_column_reduce) # [99 67 60 61 45]
max(a, b)
将 a
和 b
视为两个整体,比较它们并返回较大的那个整体。np.maximum(a, b)
则对 a
和 b
(支持广播机制)进行逐元素比较,返回一个由每个位置较大元素组成的新数组:
a = np.array([3, 7, 1])
b = np.array([4, 2, 8])
print("max(a, b):", max(a, b)) # 比较两个数组整体,返回整个数组a或b
print("np.maximum(a, b):", np.maximum(a, b)) # 逐元素比较,返回新数组
# 输出:
# max(a, b): [4 2 8] # 整体比较,b数组“大于”a数组?这通常不是我们想要的结果
# np.maximum(a, b): [4 7 8] # 逐元素比较:max(3,4)=4; max(7,2)=7; max(1,8)=8
np.fmax()
和 np.fmin()
在处理 NaN
值时非常有用,它们会忽略 NaN
并返回另一个非 NaN 的值。这与 np.maximum()
和 np.minimum()
的行为不同,后者在遇到 NaN
时通常也会返回 NaN
:
a = np.array([1.0, np.nan, 3.0])
b = np.array([2.0, 4.0, np.nan])
print(np.fmax(a, b)) # 输出: [2. 4. 3.] (忽略NaN)
print(np.maximum(a, b)) # 输出: [ 2. nan nan] (NaN会被传播)
4. 位操作函数
函数名 | 基本功能 | 运算符等价形式 |
---|---|---|
bitwise_and(x1, x2) |
逐元素计算按位与 | x1 & x2 |
bitwise_or(x1, x2) |
逐元素计算按位或 | x1 | x2 |
bitwise_xor(x1, x2) |
逐元素计算按位异或 | x1 ^ x2 |
invert(x) |
逐元素计算按位取反 (非) | ~x |
left_shift(x1, x2) |
将整数的位向左移位 | x1 << x2 |
right_shift(x1, x2) |
将整数的位向右移位 | x1 >> x2 |
注意事项:
- 位操作函数要求参数是整数类型,因为这些函数直接操作数据的底层二进制表示,直接对整数在内存中的二进制位(
bit
)进行逻辑运算,而不是对数值本身进行数学运算。 - 使用按位运算符
&
和|
时需要确保理解运算符优先级,如(a > 2) & (a < 5)
是正确语法,因为a > 2 & a < 5
会由于先计算2 & a
而导致错误。
示例 1 ,逐位进行逻辑与操作,只有两个数的对应位都为 1
时,结果位才为 1
:
# 使用函数
a = np.array([5, 10, 15, 20], dtype=np.int32)
b = np.array([12, 12, 12, 12], dtype=np.int32)
result_func = np.bitwise_and(a, b) # 输出: [ 4 8 12 4]
print("bitwise_and 函数结果:", result_func)
# 使用运算符
result_operator = a & b
print(result_operator) # 输出: [ 4 8 12 4]
示例 2 ,逐位进行逻辑或操作,只要两个数的对应位有一个为 1
,结果位就为 1
:
# 使用函数
a = np.array([1, 2, 3, 4], dtype=np.int32)
b = np.array([4, 3, 2, 1], dtype=np.int32)
result_func = np.bitwise_or(a, b)
print( result_func) # 输出: [5 3 3 5]
# 使用运算符
result_operator = a | b
print( result_operator) # 输出: [5 3 3 5]
示例 3 ,逐位进行比较,如果两个数的对应位不相同,结果位为 1
,相同则为 0
:
# 使用函数
a = np.array([5, 10, 15, 20], dtype=np.int32)
scalar = 12
result_func = np.bitwise_xor(a, scalar)
print(result_func) # 输出: [ 9 6 3 24]
# 使用运算符
result_operator = a ^ scalar
print(result_operator) # 输出: [ 9 6 3 24]
示例 4 ,将数值的二进制表示中的每一位进行取反操作(0
变 1
,1
变 0
):
# 无符号整数类型
arr_unsigned = np.array([13], dtype=np.uint8)
result_unsigned = np.invert(arr_unsigned)
print("无符号整数取反:", result_unsigned) # 输出: [242]
print("二进制表示:", np.binary_repr(result_unsigned[0], width=8)) # 输出: 11110010
# 有符号整数类型
arr_signed = np.array([13], dtype=np.int8)
result_signed = np.invert(arr_signed)
print("有符号整数取反:", result_signed) # 输出: [-14]
print("二进制表示:", np.binary_repr(result_signed[0], width=8)) # 输出: 11110010
# 使用运算符
result_operator = ~arr_unsigned
print("使用 ~ 运算符结果:", result_operator) # 输出: [242]
示例 5 ,将整数的二进制位向左移动指定的位数,右侧空位补 0
。左移 n
位相当于乘以 2 n 2^n 2n :
# 使用函数
result_func = np.left_shift(10, 2)
print("left_shift 函数结果:", result_func) # 输出: 40
# 使用运算符
result_operator = 10 << 2
print("使用 << 运算符结果:", result_operator) # 输出: 40
# 查看二进制表示变化
print("10 的二进制:", np.binary_repr(10, width=8)) # 输出: 00001010
print("40 的二进制:", np.binary_repr(40, width=8)) # 输出: 00101000
示例 6 ,将整数的二进制位向右移动指定的位数,左侧空位补 0
(对于无符号整数)。右移 n
位相当于除以 2 n
并向下取整:
# 使用函数
result_func = np.right_shift(40, 2)
print("right_shift 函数结果:", result_func) # 输出: 10
# 使用运算符
result_operator = 40 >> 2
print("使用 >> 运算符结果:", result_operator) # 输出: 10
# 查看二进制表示变化
print("40 的二进制:", np.binary_repr(40, width=8)) # 输出: 00101000
print("10 的二进制:", np.binary_repr(10, width=8)) # 输出: 00001010
5. 浮点函数
浮点函数专门设计用来高效、正确地处理浮点数数组及其特有的运算问题。
函数名 | 主要功能 | 返回值/输出说明 |
---|---|---|
isfinite |
检测数组中的每个元素是否是有限数(即既不是无穷大,也不是 NaN ) |
布尔数组(True 表示对应元素是有限数) |
isinf |
检测数组中的每个元素是否是无穷大(包括正无穷和负无穷) | 布尔数组(True 表示对应元素是无穷大) |
isnan |
检测数组中的每个元素是否是 NaN |
布尔数组(True 表示对应元素是 NaN ) |
isnat |
检测 datetime64 类型数组中的每个元素是否是 NaT (Not a Time ) |
布尔数组(True 表示对应元素是 NaT ) |
fabs |
计算数组每个元素的绝对值(对于复数是模长) | 浮点数或复数数组 |
signbit |
检测数组每个元素的符号位是否设置(即是否为负数) | 布尔数组(True 表示对应元素是负数) |
copysign |
将第一个数组的符号逐元素更改为第二个数组对应元素的符号 | 浮点数数组 |
nextafter |
返回第一个数组朝向第二个数组的下一个可表示的浮点数(逐元素) | 浮点数数组 |
spacing |
返回数组中每个元素与最近邻可表示浮点数之间的距离(ULP) | 浮点数数组 |
modf |
将数组的每个元素分离为小数部分和整数部分(逐元素) | 两个浮点数数组(一个包含小数部分,一个包含整数部分) |
ldexp |
计算第一个数组乘以 2 的第二个数组次方(x1 * 2x2 ,逐元素) |
浮点数数组 |
frexp |
将数组的每个元素分解为尾数(mantissa )和二进制指数(exponent )(逐元素) |
两个数组(一个包含尾数,一个包含指数) |
fmod |
计算除法的余数(逐元素) | 浮点数数组 |
floor |
对数组每个元素进行向下取整 | 浮点数数组 |
ceil |
对数组每个元素进行向上取整 | 浮点数数组 |
trunc |
对数组每个元素进行截断取整(向零取整) | 浮点数数组 |
示例:
# 创建一个包含多种特殊值的示例数组
arr = np.array([1.0, np.inf, -np.inf, np.nan, 0.0, -2.5, 3.14])
# 使用 isfinite, isinf, isnan 进行检测
print("原始数组:", arr)
print("isfinite (是否有限):", np.isfinite(arr)) # [ True False False False True True True]
print("isinf (是否无穷):", np.isinf(arr)) # [False True True False False False False]
print("isnan (是否NaN):", np.isnan(arr)) # [False False False True False False False]
# 使用 fabs 计算绝对值
print("fabs (绝对值):", np.fabs(arr)) # [1. inf inf nan 0. 2.5 3.14]
# 使用 signbit 检查符号位(是否为负)
print("signbit (是否为负):", np.signbit(arr)) # [False False True False True False False]
# 使用 copysign 更改符号
positive_arr = np.array([1.0, 2.0, 3.0])
negative_sign = np.array([-1.0, -1.0, -1.0])
print("copysign (更改符号):", np.copysign(positive_arr, negative_sign)) # [-1. -2. -3.]
# 使用 floor, ceil, trunc 进行取整
arr_to_round = np.array([-1.7, 1.2, 3.8])
print("floor (向下取整):", np.floor(arr_to_round)) # [-2. 1. 3.]
print("ceil (向上取整):", np.ceil(arr_to_round)) # [-1. 2. 4.]
print("trunc (向零取整):", np.trunc(arr_to_round)) # [-1. 1. 3.]
# 使用 modf 分离整数和小数部分
fractional_part, integral_part = np.modf(np.array([3.14, -2.718]))
print("modf (小数部分):", fractional_part) # [ 0.14 -0.718]
print("modf (整数部分):", integral_part) # [ 3. -2.]
# 使用 fmod 计算余数
print("fmod (余数):", np.fmod(np.array([7.0, -7.0]), np.array([3.0, 3.0]))) # [ 1. -1.]