2016-06-27 3 views
1

私のタイムラインは、私は時間ベクトルにジャンプに表示マシンのシャットダウンを検出する必要が避けパイソンループ

シンプルnumpyのアレイに保存されている、と彼らは長い(> 10百万entrys)されています。そのシャットダウン後、次の10個の値を削除したい(スイッチがオンにされてからセンサーがしばらくの間悪い結果を出す)。

私は、次のコードを思い付いた:

Keep_data=np.empty_like(Timestamp_new,dtype=np.bool)         
Keep_data[0]=False 
Keep_data[1:]=Timestamp_new[1:]>(Timestamp_new[:-1]+min_shutdown_length) 

for item in np.nonzero(np.logical_not(Keep_data))[0]: 
    Keep_data[item:min(item+10,len(Keep_data)]=False 

Timestampnew=Timestampnew[Keep_data] 

は、誰もが純粋なのpythonループせずに、より効果的なコードをお勧めすることはできますか?

ありがとうございます。

答えて

2

基本的には、拡大/拡大または画像処理の用語でdilateFalseの領域を使用しています。同じ場合は、scipy's binary_dilationというビルトインが組み込まれています。さて、入力配列Keep_dataのより高いインデックスへのそのようなFalse要素のそれぞれから始めて、それを成長させようとしています。だから、別のオフセット(またはscipyはそれをoriginと呼ぶ)を、デフォルトのものよりも0として使用する必要があります。それ以外の場合は、各要素の両端で拡張されます。

N = 10 # Interval length 
dilated_mask = binary_dilation(~Keep_data, structure=np.ones(N),origin=-int(N/2)) 
Keep_data[dilated_mask] = False 

近いだろう代替的アプローチ -

したがって、合計することで実装は、コードの愚か部分を取り除くために、我々はそうのような実装を持っているでしょうNumPy's broadcasting featureでベクトル化問題の愚かコードとして掲載一つだけに、このようになります -

N = 10 # Interval length 
idx = np.nonzero(np.logical_not(Keep_data[:-N]))[0] 
Keep_datac[(idx + np.arange(N)[:,None]).ravel()] = False 
rest = np.nonzero(np.logical_not(Keep_data[-N:]))[0] 
if len(rest)>0: 
    Keep_datac[-N+rest[0]:] = False 
+0

拳solutuionはオリジナルバージョン、BUよりも遅くなるように思われます第2のものは私にとって素晴らしい作品です。 1つの欠点は、clipingが – Okapi575

+0

@ user3373796で行われていることです。あなたの 'min()'と同じ仕事をするためにはクリッピングが必要です。正確にそれの欠点は何ですか? – Divakar

+0

欠点は、最後のインデックスだけでなく、すべての値に対してクリップが行われていることです。しかし、2番目の考えではわずか10%です。 とても役に立ちました。 – Okapi575