【问题标题】:Python - abs vs fabsPython - abs 与 fabs
【发布时间】:2012-06-02 02:12:28
【问题描述】:

我注意到在 python 中有两种相似的查找数字绝对值的方法:

第一

abs(-5)

第二

import math
math.fabs(-5)

这些方法有何不同?

【问题讨论】:

    标签: python


    【解决方案1】:

    math.fabs()如果可以(如果不能,它会抛出异常),将其参数转换为float。然后它采用绝对值,并将结果返回为float。

    除了floats,abs()还与整数和复数号一起使用。其返回类型取决于其参数的类型。

    In [7]: type(abs(-2))
    Out[7]: int
    
    In [8]: type(abs(-2.0))
    Out[8]: float
    
    In [9]: type(abs(3+4j))
    Out[9]: float
    
    In [10]: type(math.fabs(-2))
    Out[10]: float
    
    In [11]: type(math.fabs(-2.0))
    Out[11]: float
    
    In [12]: type(math.fabs(3+4j))
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    /home/npe/<ipython-input-12-8368761369da> in <module>()
    ----> 1 type(math.fabs(3+4j))
    
    TypeError: can't convert complex to float
    

    【讨论】:

    • abs 不仅适用于整数和浮点数,而且结果类型 not 始终与参数相同,例如abs(3+4j)。 span>
    • 在评论中添加关于 fabs 由于其始终浮动的特性而需要更长时间的评论,您就得到了正确的答案!
    • @ agf:谢谢你提醒我关于复数的数字。出于兴趣,__builtin__.abs() 还可以成功应用于哪些其他类别的事物?
    • @aix 任何定义__abs__魔术方法的用户定义类
    • 为什么有人会在 Python 中使用 fabs() 而不是 abs(),在这种情况下,事情似乎会根据需要在 int 和 float 之间自动转换?谢谢。
    【解决方案2】:

    math.fabs() 总是返回浮点数,而abs() 可能返回整数。

    【讨论】:

    • abs 可能返回任何类型,具体取决于调用它的类型的 __abs__ 特殊方法。
    【解决方案3】:

    编辑:正如@a​​ix建议,更好(更公平)比较速度差异:

    In [1]: %timeit abs(5)
    10000000 loops, best of 3: 86.5 ns per loop
    
    In [2]: from math import fabs
    
    In [3]: %timeit fabs(5)
    10000000 loops, best of 3: 115 ns per loop
    
    In [4]: %timeit abs(-5)
    10000000 loops, best of 3: 88.3 ns per loop
    
    In [5]: %timeit fabs(-5)
    10000000 loops, best of 3: 114 ns per loop
    
    In [6]: %timeit abs(5.0)
    10000000 loops, best of 3: 92.5 ns per loop
    
    In [7]: %timeit fabs(5.0)
    10000000 loops, best of 3: 93.2 ns per loop
    
    In [8]: %timeit abs(-5.0)
    10000000 loops, best of 3: 91.8 ns per loop
    
    In [9]: %timeit fabs(-5.0)
    10000000 loops, best of 3: 91 ns per loop
    

    所以它看起来abs()只有fabs() Integers的略微速度优势。 for floats,abs()fabs()展示类似的速度。


    除了@aix说过,还有一件事要考虑是速度差:

    In [1]: %timeit abs(-5)
    10000000 loops, best of 3: 102 ns per loop
    
    In [2]: import math
    
    In [3]: %timeit math.fabs(-5)
    10000000 loops, best of 3: 194 ns per loop
    

    so abs() @速度比math.fabs()

    【讨论】:

    • 您不会将苹果与苹果进行比较。使用from math import fabs肯定,并尝试-5.0两者。 span>
    • 也是不可靠的时序结果?您首先在102NS时具有ABS(-5),然后以后将其显示为88.3ns。永远不要从任何基准中得出结论,即使内部尝试以避免问题,它也会避免问题。 span>
    • 两个更多点:这仍然比较苹果和橙子,因为在内置镜筒中查找了ABS,而FABS在模块名称空间中。然后“XABS = ABS”然后XABS(NUM)删除该效果。此外,通过Python 3.2的情况会更改一点,显然ABS()至少有点更快(> 2x),至少在浮点数上。 span>
    • @ peterhansen你是对的,那些在不同的系统负载下的两次运行。虽然在同一组测试集中进行比较时,相对差异仍然有效。此外,谢谢你指出命名空间差异 - 我没有考虑一下。我没有尝试过3.2,但这很高兴知道!我会在你的建议中更新我的答案:)再次谢谢! span>
    【解决方案4】:

    abs(): 根据参数返回绝对值,即如果参数为 int,则返回 int,如果参数为 float,则返回 float。 它也适用于复杂变量,即abs(a+bj)也适用并返回绝对值,即math.sqrt(((a)**2)+((b)**2)

    math.fabs() : 它仅适用于整数或浮点值。无论参数类型是什么(复数除外),始终返回绝对浮点值。

    【讨论】:

      猜你喜欢
      • 2014-03-26
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多