2017-01-14 22 views
3

私は、閾値以下の「不良値」をデフォルト値に置き換えようとしています(例えばNaNに設定するなど)。 私は1000k値以上のnumpy配列をunsingしています - そのためパフォーマンスが問題です。リストの値の上下をPythonのデフォルト値に置き換えますか?

私のプロトタイプは2つのステップで動作しますが、1つのステップでこれを行うためのpssoibilityはありますか?他の多くの機能と同様に、この関連質問(Pythonic way to replace list values with upper and lower bound (clamping, clipping, thresholding)?

にコメントしたように

import numpy as np 

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

upper_threshold = 7 
lower_threshold = 1 
default_value = np.NaN 

# is it possible to do this in one expression? 
data[data > upper_threshold] = default_value 
data[data < lower_threshold] = default_value 

print data # [ nan 1. 2. 3. 4. 5. 6. 7. nan nan] 

、np.clipは、Pythonであり、それは、方法をarr.clipする延期します。メソッドがコンパイルされた通常の配列の場合、高速になります(約2倍)。 - hpaulj

事前に感謝します。

答えて

2

使用は、結合されたマスクを一度にboolean-indexing -

data[(data > upper_threshold) | (data < lower_threshold)] = default_value 

ランタイムテスト - 私たちは、任意のより良い提案one-pass-indexing方法で実行されているよう

In [109]: def onepass(data, upper_threshold, lower_threshold, default_value): 
    ...:  mask = (data > upper_threshold) | (data < lower_threshold) 
    ...:  data[mask] = default_value 
    ...: 
    ...: def twopass(data, upper_threshold, lower_threshold, default_value): 
    ...:  data[data > upper_threshold] = default_value 
    ...:  data[data < lower_threshold] = default_value 
    ...:  

In [110]: upper_threshold = 7 
    ...: lower_threshold = 1 
    ...: default_value = np.NaN 
    ...: 

In [111]: data = np.random.randint(-4,11,(1000000)).astype(float) 

In [112]: %timeit twopass(data, upper_threshold, lower_threshold, default_value) 
100 loops, best of 3: 2.41 ms per loop 

In [113]: data = np.random.randint(-4,11,(1000000)).astype(float) 

In [114]: %timeit onepass(data, upper_threshold, lower_threshold, default_value) 
100 loops, best of 3: 2.74 ms per loop 

は見えません。その理由は、マスクの OR-ingの計算がブール値インデックスそれ自体に値を直接割り当てるよりも少し高価になる可能性があるからです。

+0

ああ、私は 'data [upper_threshold> data> upper_threshold]] = default_value'を試してエラーを発生させました。これは複数の条件を追加する方法です - ありがとうございます。 – ppasler

+1

'> ...>'はスカラーPython式でのみ動作します。 'numpy'は明示的に'または/および 'を必要とします。 '()'も重要です。 – hpaulj

関連する問題