web-dev-qa-db-ja.com

リスト値を上限と下限(クランプ、クリッピング、しきい値)に置き換えるPythonの方法は?

リストからアウトライナーを置き換えたい。したがって、私は上限と下限を定義します。これで、upper_boundより上およびlower_boundより下のすべての値がバインドされた値に置き換えられます。私のアプローチは、numpy配列を使用して2つのステップでこれを行うことでした。

パフォーマンスと読みやすさを向上させることができると思うので、これを1つのステップで実行できるかどうか疑問に思います。

これを行うためのより短い方法はありますか?

import numpy as np

lowerBound, upperBound = 3, 7

arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arr[arr > upperBound] = upperBound
arr[arr < lowerBound] = lowerBound

# [3 3 3 3 4 5 6 7 7 7]
print(arr)
21
ppasler

numpy.clipを使用できます:

In [1]: import numpy as np

In [2]: arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [3]: lowerBound, upperBound = 3, 7

In [4]: np.clip(arr, lowerBound, upperBound, out=arr)
Out[4]: array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])

In [5]: arr
Out[5]: array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])
32
arthur

numpyに依存しない代替手段については、いつでも実行できます。

_arr = [max(lower_bound, min(x, upper_bound)) for x in arr]
_

上限を設定したいだけの場合は、もちろんarr = [min(x, upper_bound) for x in arr]と書くことができます。または、同様に、下限が必要な場合は、代わりにmaxを使用します。

ここでは、一緒に記述された両方の操作を適用しました。

編集:もう少し詳細な説明があります:

配列の要素xが与えられた場合(そして、_upper_bound_が少なくとも_lower_bound_と同じ大きさであると仮定すると)、次の3つのケースのいずれかになります。

i)_x < lower_bound_

ii)_x > upper_bound_

iii)_lower_bound <= x <= upper_bound_。

(i)の場合、_max/min_式は最初にmax(lower_bound, x)に評価され、次に_lower_bound_に解決されます。

(ii)の場合、式は最初にmax(lower_bound, upper_bound)になり、次に_upper_bound_になります。

(iii)の場合、max(lower_bound, x)を取得します。これはxだけに解決されます。

3つのケースすべてで、出力は必要なものです。

13
mathmandan