HOWTO · NumPy

在 NumPy 中计算绝对值

NumPy 中有 3 种方法可用于计算绝对值,分别是 abs() 函数、numpy.absolute() 函数和 numpy.abs() 函数。

本页内容

计算绝对值是数据分析和科学计算中的一项基本操作。在 Python 中,NumPy 库提供了在数组和数值数据上高效执行这一操作的方法。无论你处理的是简单的数字列表,还是复杂的多维数组,理解如何计算绝对值都能提升你的数据处理能力。

在本文中,我们将探讨在 NumPy 中计算绝对值的三种主要方法:abs() 函数、numpy.absolute() 和 numpy.abs()。三者关系密切——对 NumPy 数组而言,它们执行的都是同一个逐元素操作——因此本指南着重说明它们真正的区别:各自接受什么样的输入,以及 NumPy 函数提供了哪些额外的控制。

使用内置函数 abs()

abs() 函数是 Python 的内置函数,返回一个数的绝对值。它虽然不是 NumPy 专属的,但可以用于 NumPy 数组:当你对数组应用 abs() 时,Python 会调用数组的 __abs__() 方法,也就是 NumPy 自身的绝对值操作,你会得到一个由原始元素绝对值组成的新数组。

下面是结合 NumPy 使用 abs() 函数的方法:

import numpy as np

array = np.array([-1, -2, 3, -4])
absolute_values = abs(array)

print(absolute_values)

输出:

[1 2 3 4]

由于 abs() 只是把调用转发给数组的 __abs__() 方法,它对数组执行的计算与 numpy.absolute() 完全相同——对 NumPy 数据使用内置函数没有任何性能损失。它真正的局限在别处:abs() 需要一个定义了 __abs__() 的对象。它可用于 Python 数字、复数和 NumPy 数组,但对普通的 Python 列表调用 abs() 会引发 TypeError,而下文的 NumPy 函数可以直接接受列表。

使用 numpy.absolute()

numpy.absolute() 是 NumPy 自身的绝对值函数,以 ufunc 形式实现。它对任意形状和大小的数组逐元素计算绝对值,并且与内置函数不同,它还接受列表等类数组输入,会先将其转换为数组。作为 ufunc,它还接受常规的 ufunc 参数,例如用 out= 把结果写入已有的数组。

下面是使用 numpy.absolute() 的示例:

import numpy as np

array = np.array([[-1, -2, 3], [-4, 5, -6]])
absolute_values = np.absolute(array)

print(absolute_values)

输出:

[[1 2 3]
 [4 5 6]]

numpy.absolute() 还支持复数,返回每个元素的模:

import numpy as np

complex_array = np.array([3 + 4j, -5 + 12j])
magnitudes = np.absolute(complex_array)

print(magnitudes)

输出:

[ 5. 13.]

这使它成为科学计算中稳妥的默认选择,因为那里的数据可能是多维的,也可能是复数。

使用 numpy.abs()

numpy.abs() 根本不是一个单独的实现:它与 numpy.absolute() 是同一个函数对象——在 NumPy 中,np.abs is np.absolute 的求值结果为 True。较短的名字纯粹是作为方便的别名存在的。

下面是 numpy.abs() 的用法:

import numpy as np

array = np.array([[1, -2], [-3, 4]])
absolute_values = np.abs(array)

print(absolute_values)

输出:

[[1 2]
 [3 4]]

由于两个名字指的是同一个函数,在 numpy.abs() 与 numpy.absolute() 之间选择只是代码风格或可读性的问题;无论选哪一个,结果和性能都完全相同。

结论

在 NumPy 中计算绝对值很简单,因为三种方法对数组执行的都是同一个逐元素操作。当你的值已经是 NumPy 数组或普通数字、并且想要写通用的 Python 代码时,使用内置的 abs();当你需要传入列表等类数组数据,或使用 out= 等 ufunc 选项时,使用 numpy.absolute() 或其别名 numpy.abs()。无论选择哪种写法,你得到的数字都是一样的。

常见问题

  1. abs() 和 numpy.absolute() 有什么区别?
    区别在接口,不在计算。对 NumPy 数组而言,abs() 调用的是数组的 __abs__() 方法,与 numpy.absolute() 执行的是同一个操作。numpy.absolute() 还额外接受列表等类数组输入和 out= 等 ufunc 参数;而 abs() 对普通列表会引发 TypeError,因为列表没有定义 __abs__()。

  2. numpy.abs() 可以用于复数吗?
    可以。三种方法都返回复数的模;例如,3 + 4j 和 -5 + 12j 的绝对值是 5.0 和 13.0,如上文 numpy.absolute() 的示例所示。

  3. 这些方法之间有性能差异吗?
    没有有意义的差异。numpy.abs() 和 numpy.absolute() 是同一个函数对象,而对数组使用 abs() 也会分派到同一个 NumPy 操作,因此三者做的逐元素工作相同;只有调用开销略有差别,且可以忽略不计。

  4. 多维数组应该使用哪种方法?
    任何一种都可以——三者都能处理任意形状的数组,如上文的二维示例所示。如果输入可能是列表或其他类数组,建议优先使用 numpy.absolute() 或 numpy.abs(),因为内置的 abs() 只接受定义了 __abs__() 的对象。

  5. 使用这些函数时输出有区别吗?
    没有。对于相同的输入,三种方法返回的值相同。