Python-absとfabs


107

私はpythonに数値の絶対値を見つけるために似た2つの方法があることに気づきました:

最初

abs(-5)

二番目

import math
math.fabs(-5)

これらの方法はどのように異なりますか?

回答:


127

math.fabs()可能であれば、引数を浮動小数点に変換します(変換できない場合は、例外をスローします)。次に、絶対値を取り、結果を浮動小数点数として返します。

浮動小数点数に加えて、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

4
abs整数と浮動小数点数だけでなく、結果の型が引数と常に同じであるとは限りませんabs(3+4j)
agf

1
fabs常に変動する性質のため、時間がかかることについてのコメントを追加すると、正しい答えが得られます!
Patrick Perini、2012年

@agf:複素数について思い出させてくれてありがとう。興味深いことに、他にどのようなクラスのものを__builtin__.abs()うまく適用できますか?
NPE、2012年

5
@aix __abs__マジックメソッドを定義するユーザー定義クラス
agf

9

編集:@aixが示唆するように、速度の違いを比較するためのより良い(より公正な)方法:

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()です。フロートの場合abs()fabs()同様の速度を示します。


@aixが言ったことに加えて、考慮すべきもう1つのことは速度の違いです。

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

そう abs()、よりも高速ですmath.fabs()


3
そこにあるリンゴとリンゴを比較するのではありません。from math import fabs確かに使用し、-5.0両方を試してください。
agf

また、タイミング結果の信頼性が低いですか?最初に102nsでabs(-5)があり、その後88.3nsと表示されました。timeitのように内部で問題を回避しようとしても、ベンチマークの1回の実行から結論を導き出さないでください。
Peter Hansen

1
さらに2つのポイント:fabsがモジュールの名前空間にある間、absは組み込み関数で検索されるため、これはまだリンゴとオレンジを比較しています。"xabs = abs"を実行し、次にxabs(num)を実行してその効果を削除します。また、Python 3.2では物事はかなり変化し、明らかにabs()はかなり高速(> 2x)で、少なくともフロート上ではそうです。
Peter Hansen

1
@PeterHansenそうです、それらは異なるシステム負荷の下での2つの実行からのものです。同じテストセット内で比較した場合でも、相対的な差は依然として有効です。また、名前空間の違いを指摘してくれてありがとう-私はそれを考慮しませんでした。3.2では試していませんが、知っておくと役に立ちます。私は少し後であなたの提案で私の答えを更新します:)再びありがとう!
KZ 2013年

3

math.fabs()常に浮動小数点数を返しますが、abs()整数を返す場合もあります。


6
abs__abs__呼び出された型の特別なメソッドに応じて、任意の型を返す場合があります。
AGF

0

abs():引数ごとに絶対値を返します。つまり、引数がintの場合はintを返し、引数がfloatの場合はfloatを返します。また、それは複雑な変数でabs(a+bj)も機能します。つまり、機能し、絶対値を返します。math.sqrt(((a)**2)+((b)**2)

math.fabs():整数値または浮動小数点値でのみ機能します。引数の型が何であっても(絶対数を除く)、常に絶対浮動小数点値を返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.