当前位置: 首页 > news >正文

NumPy 2.x 完全指南【三十二】通用函数(ufunc)之数学运算函数

文章目录

  • 1. 什么是通用函数
  • 2. 数学运算函数
    • 2.1 四则运算
    • 2.2 取余运算
    • 2.3 绝对值
    • 2.4 指数
    • 2.5 对数
    • 2.6 平方、非负平方根、立方根
    • 2.7 幂运算
    • 2.8 最大公约、最小公倍数
    • 2.9 四舍五入、倒数、正值、负值
    • 2.10 复数共轭运算
    • 2.11 矩阵乘积
    • 2.12 符号、阶跃函数

1. 什么是通用函数

通用函数(简称 ufunc)是一种能对数组中的每个元素进行高效逐元素操作的函数,支持数组广播、类型转换以及若干其他标准特性。

核心特性:

  • 广泛适用:许多操作(如加法、乘法、排序、转换等)可以同时作用于标量、向量、矩阵等不同的数据结构。
  • 逐元素操作:对输入数组的每个元素独立执行相同操作,返回同形状的结果数组。
  • 高效:通常由底层 C 语言或其他高效语言实现,因此即使是复杂的操作,也能实现较高的执行效率,避免了纯 Python 实现的性能瓶颈。
  • 自动处理广播机制:通用函数能够自动处理广播机制,允许不同形状的数组进行运算而无需显式地调整它们的形状。

目前 NumPy 中的定义了 60 多个通用函数,支持多种数据类型(如整数、浮点数、复数)等,涵盖了各种各样的操作。在使用相关的中缀符号时会在数组上自动调用通用函数,例如 a + b 内部会调用 add(a, b))

2. 数学运算函数

2.1 四则运算

函数名等效运算符描述
numpy.add()+逐元素加法
numpy.subtract()-逐元素减法
numpy.multiply()*逐元素乘法
numpy.divide()/逐元素真除法
numpy.true_divide()/divide
numpy.floor_divide()//逐元素地板除法(向下取整)

示例 1 ,各种基础运算操作:

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])# 数组相加
result = np.add(a, b)  # 等价于: a + b
print(result)  # [5, 7, 9]# 数组相减
result = np.subtract(a, b)  # 等价于: a - b
print(result)  # [-3 -3 -3]# 数组相乘
result = np.multiply(a, b)  # 等价于: a * b
print(result)  # [ 4 10 18]# 整数除法(返回浮点结果)
result = np.divide(a, b)  # 等价于: a / b
print(result.dtype)  # float64
print(result)  # [0.25 0.4  0.5 ]# 向下取整除法
result = np.floor_divide(a, b)
print(result)  # [0 0 0]

示例 2 ,形状不同的数组会自动广播:

# 广播机制(形状不同)
c = np.array([[1, 2], [3, 4]])
d = np.array([10, 20]) # 广播为 [[10, 20],[10, 20]]
result = np.add(c, d)
print(result) # [[11, 22], [13, 24]]

2.2 取余运算

函数名等效运算符描述
remainder(x1, x2)%返回除法的逐元素余数
mod(x1, x2)%remainder
fmod(x1, x2)返回除法的逐元素余数(使用 Cfmod 函数)
divmod(x1, x2)同时返回逐元素的商和余数

示例 1 ,简单余数计算:

a = np.array([7, -7, 10])
b = np.array([3, 3, 0])# 基本余数计算
result = np.remainder(a, b)  # 等价 np.mod
print(result)  # [1, 2, 0]# 负数的余数计算
print(np.remainder([-3, -7], [-2, 3]))  # [-1  2]

示例 2 ,numpy.fmod() 会直接调用 C 库的 fmod 函数,主要区别是余数符号与被除数相同:

# 余数符号取决于被除数
print(np.remainder([-7, 7], [3, -3]))  # [ 2 -2]
print(np.fmod([-7, 7], [3, -3]))  # [-1, 1]

示例 3 ,divmod() 可以同时获取商和余数:

quot, rem = np.divmod([10, 25, 37],[3, 7, 4])
print(quot)  # [3, 3, 9](商向下取整)
print(rem)  # [1, 4, 1](余数)

2.3 绝对值

函数名等效运算符描述
absolute(x)逐元素计算绝对值。
fabs(x)逐元素计算绝对值(针对浮点数)。
示例 1 ,计算绝对值:
# 实数计算(两者结果一致)
x = np.array([-1.5, -3, 0, 2.5])
print(np.absolute(x))  # [1.5 3.  0.  2.5]
print(np.fabs(x))      # [1.5 3.  0.  2.5]# 整数输入时的类型差异
y = np.array([-10, 20])abs_result = np.absolute(y)
print(abs_result.dtype) # int64
print(abs_result) # [10 20]fabs_result = np.fabs(y)
print(fabs_result.dtype) # float64
print(fabs_result) # [10. 20.]

2.4 指数

函数名数学公式描述
exp(x)exe^xex以自然常数为底,元素为指数
exp2(x)2x2^x2x2 为底,元素为指数
expm1(x)ex−1e^x - 1ex1以自然常数为底,元素为指数,并 -1

示例 1 ,以 eee 为底:

print(np.exp(3))          # 20.0855 (e³ ≈ 20.0855)
print(np.exp([0, 1, 2]))  # [1.0, 2.7183, 7.3891]

示例 2 ,以 222 为底:

print(np.exp2(3))          # 8.0 (2³=8)
print(np.exp2([1, 3, 5]))  # [2.0, 8.0, 32.0]

示例 3 ,np.expm1() 用于计算 ex−1e^x - 1ex1 时,尤其在 xxx 接近零时能避免精度损失:

x_small = 1e-10 # 科学计数法 0.0000000001# 直接计算导致精度损失
direct_calc = np.exp(x_small) - 1
print(direct_calc) # 1.000000082740371e-10 :0.0000000001000000082740371# 使用 expm1 保持精度
expm1_calc = np.expm1(x_small)
print(expm1_calc) # 1.00000000005e-10 # 0.000000000100000000005

2.5 对数

函数名数学公式描述
logaddexp(x1, x2)ln(ex1+ex2)ln(e^{x_1} + e^{x_2})ln(ex1+ex2)以自然常数为底,逐元素计算 ex1+ex2e^{x_1} + e^{x_2}ex1+ex2 的对数
logaddexp2(x1, x2)log2(2x1+2x2)log_2(2^{x_1} + 2^{x_2})log2(2x1+2x2)2 为底,逐元素计算 2x1+2x22^{x_1} + 2^{x_2}2x1+2x2 的对数
log(x)ln(x)ln(x)ln(x)以自然常数为底,逐元素计算对数
log1p(x)ln(1+x)ln(1 + x)ln(1+x)以自然常数为底,逐元素 +1 计算对数
log2(x)log2(x)log_2(x)log2(x)2 为底,逐元素计算对数
log10(x)log10(x)log_{10}(x)log10(x)10 为底,逐元素计算对数

示例 1 ,最简单的标量使用 logaddexp() 函数:

x1, x2 = 1, 1
result = np.logaddexp(x1, x2)
print(result) # 1.6931471805599454

其计算过程的数学表达式为:
result=ln⁡(e1+e1)=ln⁡(2⋅e1)result= \ln(e^{1} + e^{1}) = \ln(2 \cdot e^{1})result=ln(e1+e1)=ln(2e1)

计算指数项:
ex1=e1≈2.71828,ex2=e1≈2.71828e^{x_1} = e^{1} \approx 2.71828, \quad e^{x_2} = e^{1} \approx 2.71828ex1=e12.71828,ex2=e12.71828
求和:
ex1+ex2=2.71828+2.71828=5.43656e^{x_1} + e^{x_2} = 2.71828 + 2.71828 = 5.43656 ex1+ex2=2.71828+2.71828=5.43656
计算对数:
ln(5.43656)≈1.693147ln(5.43656) \approx 1.693147 ln(5.43656)1.693147

2.6 平方、非负平方根、立方根

函数名数学公式描述
square(x)$ \sqrt{x} $返回输入的逐元素平方
sqrt(x)$ x^2 $返回数组的逐元素非负平方根
cbrt(x)x3\sqrt[3]{x}3x返回数组的逐元素立方根

示例 1 :

# 平方
print(np.square([3, -2, 1.5]))      # [9, 4, 2.25](浮点数)
print(np.square([2, -3]))            # [4, 9](整数)# 非负平方根
print(np.sqrt([4, 9, 16]))          # [2.0, 3.0, 4.0]
print(np.sqrt([-4, 0, 4]))          # [nan, 0.0, 2.0] (负数返回 nan )触发警告:RuntimeWarning# 立方跟
print(np.cbrt([8, -8, 27]))         # [2.0, -2.0, 3.0]

2.7 幂运算

函数名数学公式描述
power(x1, x2)$ (x_1^{x_2} $第一个数组元素逐元素地提升到第二个数组中元素的幂次。
float_power(x1, x2)$ (x_1^{x_2} $第一个数组元素逐元素地提升到第二个数组中元素的幂次(提升为浮点数)。

示例 1 ,power(x1, x2) 计算数组 x1x1x1 中每个元素对 x2x2x2 对应元素的幂次,即 x1x2x_1^{x_2}x1x2

# 整数幂运算
a = [2, 3]
b = [2, 2]
print(np.power(a, b))  # 输出: [4 9]

示例 2 ,float_power(x1, x2) 执行幂运算时强制将输入提升为 float64 ,以保证精度:

# 负指数与浮点结果
print(np.float_power(2, -3))  # 输出: 0.125(浮点数)

2.8 最大公约、最小公倍数

函数名数学公式描述
gcd(x1, x2)最大公约数返回 `
lcm(x1, x2)最小公倍数返回 `

对于整数 aaabbb,最大公约数(GCD)是能同时整除 aaabbb 的最大正整数,最小公倍数(LCM)是能被 aaabbb 同时整除的最小正整数。

示例 1 :

# 最大公约数
print(np.gcd(12, 18))          # 输出: 6
print(np.gcd([-12, 0], [18, 5]))  # 输出: [6, 5](负数取绝对,0取非零值)# 最小公倍数
print(np.lcm(12, 18))          # 输出: 36
print(np.lcm([-4, 3], [6, 0]))    # 输出: [12, 0](负数结果非负,含0返回0)

2.9 四舍五入、倒数、正值、负值

函数名数学公式描述
rint(x)四舍五入整数将数组的元素四舍五入到最接近的整数
reciprocal(x)$ 1/x $返回数组的逐元素倒数
negative(x)−x-xx返回数组的逐元素数值负值
positive(x)+x+x+x返回数组的逐元素数值正值(通常返回副本)

示例 1 ,rint(x) 遵循 IEEE 754 标准,即四舍六入五取偶,1.5 默认舍入为 2.0(偶舍入):

print(np.rint([1.4, 1.5, 2.5, 2.6, -2.2]))  # 输出: [ 1.  2.  2.  3. -2.]

示例 2 ,reciprocal(x) 倒数函数对整数输入可能因截断导致错误结果,优先使用浮点数精确计算:

# 浮点数示例
print(np.reciprocal([2.0, 4.0, 0.5]))  # 输出: [0.5, 0.25, 2.0]# 整数示例(注意截断问题!)
print(np.reciprocal([2, 4, 3]))        # [0 0 0]

示例 3 ,reciprocal(x) 符号反转,数值不变:

# 基本示例
print(np.negative([3.0, -2.5, 0]))  # 输出: [-3.0, 2.5, 0]# 特殊值处理
print(np.negative([np.inf, -0.0]))  # 输出: [-inf, 0.0]

示例 4 ,positive(x) 等价于对每个元素执行 +x 操作,这意味着它不会改变输入值的数值大小或符号,而是直接返回元素本身的值。通常返回副本,可用于强制复制数据或处理符号:

# 基本示例
arr = np.array([-3.0, 5.0, -0.0])
print(np.positive(arr))  # 输出: [-3.0, 5.0, -0.0]# 特殊值处理
print(np.positive([-0.0, np.nan]))  # 输出: [-0.0, nan]

2.10 复数共轭运算

函数名数学公式描述
conj(x)$ (x_1^{x_2} $逐元素返回复数共轭
conjugate(x)$ (x_1^{x_2} $conj

对于复数 z=a+bjz = a + bjz=a+bjaaa 为实部,bbb 为虚部),其共轭复数记为 zˉ\bar{z}zˉz∗z^*z,定义为:
zˉ=a−bj\bar{z} = a - bj zˉ=abj

示例 1:

np.conjugate(1+2j)  # 返回 (1-2j) [1,2,7](@ref)
x = np.array([[1+1j, 0], [0, 1+3j]])
np.conj(x)  # 返回 [[1-1j, 0-0j], [0-0j, 1-3j]] [1,6](@ref)

2.11 矩阵乘积

函数名数学公式描述
matmul(x1, x2)线性代数矩阵乘法两个数组的矩阵乘积

示例 1 ,计算两数组的矩阵乘积,遵循线性代数规则

A = np.array([[1, 2], [3, 4]])
B = np.array([5, 6])
print(A @ B)  # 输出:[17, 39](矩阵与向量乘法)

2.12 符号、阶跃函数

符号函数用于提取实数的符号信息正、负或零),而忽略其具体数值大小。是一个分段函数,定义为:
sgn(x)={1若 x>0(正数)0若 x=0(零)−1若 x<0(负数)\text{sgn}(x) = \begin{cases} 1 & \text{若 } x > 0 \quad \text{(正数)} \\ 0 & \text{若 } x = 0 \quad \text{(零)} \\ -1 & \text{若 } x < 0 \quad \text{(负数)} \end{cases} sgn(x)=101 x>0(正数) x=0() x<0(负数)
示例 1 ,符号函数:

print(np.sign([-2, 0, 3j]))  # 输出:[-1, 0, 1+0j]

示例 2 ,阶跃函数:

np.heaviside([-1.5, 0, 2.0], 0.5)  # 输出:[0.0, 0.5, 1.0]
http://www.dtcms.com/a/356058.html

相关文章:

  • 面试tips--JVM(1)--对象分配内存的方式TLAB
  • CTFshow系列——命令执行web61-68
  • C++之多态篇
  • 君正T31学习(四)- MT7682+VLC出图
  • 【python】python进阶——as关键字
  • 程序代码篇---类
  • SpringCloud Alibaba Nacos 注册中心/配置中心
  • SpringBoot 配置文件在运维开发中的应用
  • 基于springboot的商业店铺租赁系统
  • 在 Vue 前端(Vue2/Vue3 通用)载入 JSON 格式的动图
  • 校园文化活动管理系统设计与实现(代码+数据库+LW)
  • web前端知识——第一阶段
  • 【buildroot】【1. Buildroot版本与Linux内核调试对应关系】
  • 基于SpringBoot的旅游景点推荐系统【2026最新】
  • 域名所有权变更,需要重新备案吗
  • Day16_【机器学习分类】
  • 软磁材料与硬磁材料
  • MTK Linux DRM分析(十九)- KMS drm_framebuffer.c
  • LeetCode 141.环形链表
  • 软考中级【网络工程师】第6版教材 第4章 无线通信网 (上)
  • 8.28 JS移动端事件
  • HTTP 范围请求:为什么你的下载可以“断点续传”?
  • 现在购买PCIe 5.0 SSD是否是最好的时机?
  • 嵌入式学习笔记--LINUX系统编程阶段--DAY02系统编程
  • 嵌入式学习日志————实验:串口发送串口发送+接收
  • 亚远景-ISO/PAS 8800:如何通过认证提升企业技术管理能力?
  • 入职体检空腹血糖 6.15mmol/L合格吗?
  • amis上传组件导入文件接口参数为base64格式的使用示例
  • NumPy 2.x 完全指南【三十一】布尔数组索引
  • ConcurrentHashMap的原理