跳至主要内容

Python 指数运算:初学者全面指南

掌握在 Python 中进行指数运算的多种方法,从内置函数到强大的 NumPy 库,并将其应用于真实场景,加深理解。
· 9分钟 阅读

使用 AI 探索

指数运算在编程的诸多领域都至关重要,从数据分析到算法设计皆是如此。其应用包括分析社交媒体趋势等大型数据集中的指数模式,以及执行复合增长或利率等数学计算。

此外,指数运算在机器学习(ML)和人工智能(AI)中也发挥着关键作用,尤其是在神经网络和图像识别中。因此,掌握如何在 Python 中高效地进行指数计算尤为重要。

在本指南中,我们将探索在 Python 中执行指数运算的多种方法。我们将考察内置函数、math 模块中的函数,以及 Numpy 库中的函数。每种方法各有优势。为进一步夯实理解、快速进阶并成为专家,欢迎报名我们的 Python Programming Fundamentals 技能路径。

Python 中的指数运算

Python 提供多种计算指数的方法:

  • **:双星号运算符(**)是进行指数运算最简单、最基础的选项。例如,x ** y 计算的是 x 的 y 次幂。

  • pow():这个内置函数接收两个参数:底数和指数,返回底数的指数次幂的结果。它还允许可选的第三个参数进行模指数运算。示例:pow(x, y)。

  • math.pow():来自 math 模块的此函数与 pow() 类似,但它始终返回浮点数结果。它接收两个参数,均可为浮点数或整数。示例:math.pow(x, y)。

  • math.exp():同样来自 math 模块,它返回一个数的自然指数值,即 e 的该参数次幂。示例:math.exp(argument)。

  • np.power():来自 NumPy 库的函数,专为数组或矩阵而设计,执行按元素的指数运算。示例:np.power(array, exponent)。

Python 指数运算基础

双星号运算符(**)是 Python 中进行指数运算最直接的方式。该运算符将左操作数(底数)提升为右操作数(指数)的幂。它也被称为幂运算符或指数运算符。

如果您想提升 Python 编程技能,学习像专业程序员那样编写代码,可以查看课程 Python Programming。

正指数

在以下代码片段中,我们展示了如何使用正指数进行指数运算。例如,2 的 3 次幂计算为 2 × 2 × 2,结果为 8。类似地,-10 的 4 次幂计算为 -10 × -10 × -10 × -10,结果为 10000。

base = 2
exponent = 3
print(base**exponent)  # Output: 8

base = -10
exponent = 4
print(base**exponent)  # Output: 10000

负指数

此代码计算将一个底数提升为负指数的结果。例如,5 的 -2 次幂等于 0.04。类似地,25 的 -5 次幂得到一个非常小的值,用科学计数法表示为 1.024e-07。

base = 5
exponent = -2
print(base**exponent) # 0.04

base = 25
exponent = -5
print(base**exponent) # 1.024e-07

将一个数提升为负指数,等价于取其对应正指数幂的倒数。

Raising a number to a negative exponent

在 Python 中,如果将 0.0 提升为负幂,** 运算符会返回 ZeroDivisionError,因为任何数除以零都是未定义的。

base = 0
exponent = -5
print(base**exponent)

输出为:

ZeroDivisionError in Python

浮点指数

以下代码示例表明,Python 能够正确计算将正底数(如 2)提升为分数指数(如 1.5)的结果。然而,对负底数使用分数指数会得到复数。

base = 2
exponent = 1.5
print(base**exponent) # 2.8284271247461903

base = -0.25
exponent = 1.25
print(base**exponent) # (-0.12500000000000003-0.125j)

更深入:内置函数

Python 提供多种用于计算指数的内置函数,但我们将重点介绍两种:pow() 和 math.pow()。乍看之下,它们似乎相似,但存在一些重要差异。

pow()

pow() 函数接收两个必需参数:底数和指数。可选地,pow() 接收第三个参数,用于计算指数值的模。其语法为:pow(base, exp, mod),其中“mod”表示模。该函数返回指数运算后的余数。

基础指数运算

对于基础计算,只需将底数和指数传入函数,其工作方式与 ** 运算符类似。

r = pow(2, 3)
print(r) # 8

r = pow(4, -10)
print(r) # 2.56e-06

浮点数指数运算

在下面的代码中,我们对底数和指数都使用浮点数,其中一些为负数。其行为与 ** 运算符类似。

r = pow(3.5, 2)
print(r)  # 12.25

r = pow(3.5, -2)
print(r)  # 0.08163265306122448

r = pow(3.5, 3.2)
print(r)  # 55.08301986166747

r = pow(-3.5, -3.3)
print(r)  # (-0.009414432347757688+0.012957854474952653j)

r = pow(-3.5, 3.3)
print(r)  # (-36.698070584660925-50.510560868902246j)

注意:如果您只需进行基础指数运算且不需要取模计算,相比 pow() 函数,** 运算符更简洁、可读性更高。

模指数运算

pow() 函数的可选模参数在进行模指数运算时非常有用。这在密码学或处理大数时尤为实用,因为模指数运算具有效率更高的优势。举例来说,计算 3 的 4 次幂对 5 取模,结果为 1,因为 81 对 5 取模等于 1。

r = pow(3, 4, 5)
print(r)  # 1

r = pow(123, 456, 789)
print(r)  # 699

r = pow(2, -3, 7)
print(r)  # 1

r = pow(-13, 8, 62)
print(r)  # 7

您可能会疑惑,为何直接使用 pow() 进行模指数运算比 pow(base, exp) % mod 或 (base**exp) % mod 更高效。原因在于内置的 pow() 函数是为该操作专门优化的,而其他方法会执行不必要的中间计算。对于大数值,这种差异会显著影响性能。

import timeit

start_pow_mod = timeit.default_timer()
pow(500000000, 3000, 4000)
stop_pow_mod = timeit.default_timer()

pow_mod_time = stop_pow_mod - start_pow_mod

print("Time using pow(base, exp, mod): ", pow_mod_time)

start_pow_other = timeit.default_timer()
pow(500000000, 3000) % 4000
stop_pow_other = timeit.default_timer()

pow_other_time = stop_pow_other - start_pow_other

print("Time using pow(base, exp) % mod:", pow_other_time)


start_aestrisk = timeit.default_timer()
(500000000**3000) % 4000
stop_aestrisk = timeit.default_timer()

aestrisk_time = stop_aestrisk - start_aestrisk

print("Time using (base ** exp) % mod: ", aestrisk_time)


print(
    f"Speed comparison: pow(base, exp, mod) was {pow_other_time / pow_mod_time} times faster than pow(base, exp) % mod and {aestrisk_time/pow_mod_time} times faster than (base ** exp) % mod"
)

输出为:

modular exponentiation in Python

pow() 函数会根据情形抛出不同的错误。

# Trying to take the modulo of complex numbers raises a ValueError.
print(pow(2 + 3j, 4, 5))  # ValueError: complex modulo

# Taking the third argument is not allowed if the second argument is negative.
print(pow(10, -11, 4))  # ValueError: base is not invertible for the given modulus

# If the first or second argument is a float, the third argument is not allowed.
print(pow(2.4, 3, 4))  # TypeError: pow() 3rd argument not allowed unless all arguments are integers

# Passing any argument as a string results in a TypeError.
print(pow(2, 4, '3'))  # TypeError: unsupported operand type(s) for pow(): 'int', 'int', 'str'

math.pow()

math.pow(x, n) 函数将 x 提升为 n 次幂。math.pow() 会将参数转换为浮点数,并以精确的浮点指数运算返回结果。这种精度在数据分析和科学计算等以准确性为首要目标的领域尤为关键。

下面是简洁的代码示例。math.pow() 返回浮点值,而 pow() 则返回整数值。

import math
print(math.pow(6, 3))  # 216.0
print(pow(6, 3))  # 216

math.pow() 函数不接受虚数。

can't convert complex to float TypeError in Python

math.pow() 不接受带分数指数的负底数,否则会引发 ValueError。

math domain error ValueError in Python

利用库进行高级指数运算

要处理更高级的指数运算任务,例如求一个数的指数值或在数组/矩阵中进行按元素的指数运算,您可以使用两个函数:np.power() 和 math.exp()。

np.power()

在 Python 中,指数运算并不局限于内置函数。NumPy 是一个功能强大的库,使我们能够对数组执行多种数学运算。有时您需要在整个数组上进行指数运算,这时 np.power() 就派上用场了。它专为数组的按元素指数运算而设计。

import numpy as np
r = np.power([2, 4, 8], 2)
print(r)  # [4, 16, 64]

r = np.power([2, 4, 8], [1, 2, 3])
print(r)  # [4 64 4096]

r = np.power([[2, 3, 4], [5, 6, 7]], [1, 2, 3])
print(r) # [[2 9 64] [5 36 343]]

np.power() 函数不接受负指数。

import numpy as np
r = np.power([2, 4, 8], -2)
print(r)

输出为:

ValueError when trying to exponentiate in Python

如果您尝试将负数提升为非整数幂,NumPy 会返回 NaN(非数值)。

image7.png

math.exp()

math.exp(x) 函数计算 x 的指数值,即将欧拉常数 e 提升为 x 次幂。欧拉常数约等于 2.71828,在数学记号中记为 e^x。

import math
x = 2
r = math.exp(x)
print("Exponential of", x, ":", r) # 7.38905609893065

math.exp(x) 的一个重要特性是其适应性。它可以处理正数、负数,甚至浮点数。

import math
print(math.exp(-2))  # 0.1353352832366127
print(math.exp(-2.5))  # 0.0820849986238988
print(math.exp(2.5))  # 12.182493960703473

实践应用与示例

指数运算是数学中的基础操作,在数据分析和科学计算中有着广泛应用。

如果您想掌握用 Python 进行数据分析的基础知识,请查看课程 Introduction to Python for Data Science。

假设您有一个 CSV 文件,其中包含多行的本金、利率和投资年限数据。您可以使用上述任何一种方法来计算每一行的复利。

Principal,Rate,Years
1000,0.05,5
2000,0.03,10
1500,0.08,3
3000,0.06,7
2500,0.04,9
1800,0.07,4
2200,0.025,6
3500,0.09,2
2800,0.035,8
4000,0.02,5

代码如下:

import csv


def compound_interest(principal, rate, years):
    return principal * (1 + rate) ** years


# Read data from CSV file

data = []
with open("data.csv", newline="") as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        row["Compound Interest"] = compound_interest(
            float(row["Principal"]), float(row["Rate"]), int(row["Years"])
        )
        data.append(row)
# Write data to a new CSV file with compound interest column

output_file = "data.csv"
fieldnames = ["Principal", "Rate", "Years", "Compound Interest"]

with open(output_file, mode="w", newline="") as csvfile:
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    for row in data:
        writer.writerow(row)
print("Compound interest calculations saved to", output_file)

结果如下:

calculating compound interest in Python

很好!您已为所有行计算了复利,并将其存储在单独的列中。您可以将这些数据用于进一步分析。同样,指数运算在其他数百种用例中也被广泛应用,例如对人口随时间的增长进行建模。

结论

在本指南中,我们探讨了在 Python 中计算指数的五种不同方法,每种方法都具备独特优势。您可以将它们用于诸多实际场景,例如求解复利、建模人口增长等。

  • 双星号运算符(**): 简单直接,适合日常使用。
  • pow(): 功能多样,并可选用“模”参数这一技巧。
  • math.pow(): 以浮点数形式返回精确结果。
  • np.power(): 处理数组的利器,并带有错误检查。
  • math.exp(): 专用于计算指数值的工具。

如果您想提升统计技能,学习如何使用 Python 采集、分析数据并得出准确结论,请查看课程 Introduction to Statistics in Python。

Satyam Tripathi

作者

Satyam Tripathi

Python 指数运算常见问答

在 Python 中,何时应使用 math.pow() 而不是 ** 运算符?

当您需要用于科学或数据分析的精确浮点结果时,请使用 math.pow()。如果追求简洁且计算不涉及浮点精度,使用 ** 运算符即可。

Python 能处理负指数或分数指数吗?

可以,Python 支持负指数和分数指数:

  • 负指数:使用 ** 运算符或 pow() 来计算一个数的正幂的倒数。
  • 分数指数:使用 ** 运算符或 math.pow()。注意:负底数配合分数指数会得到复数。
Python 中如何实现模指数运算,为何它更高效?

可以使用带三个参数的 pow() 函数进行模指数运算:pow(base, exp, mod)。它比计算 (base**exp) % mod 更高效,因为 pow() 针对大数做了优化,减少了中间计算。

为什么 NumPy 的 np.power() 对负指数会报错?

np.power() 专为数组计算而设计,不支持负指数,因为负指数意味着除法,这与所有数组类型并不兼容。此类计算可改用 ** 或 pow()。

主题