2016-12-31 5 views
4

時々行が0になるようなセンサの読み方の大きなデータセットがあります。ヒューリスティックは非常に簡単です。前の行と次の行が0でない場合、私はこれがセンサの不具合であると仮定し、この行をその周りの2つの平均で置き換えます。pandas.DataFrameを3行ずつ繰り返し処理する必要があるデータのクリーンアップ

センサの読み取り値が0になる可能性があるため、単に0を見ることはオプションではありません。

これまでのところ、私はそれをクリーンアップするために、以下の方法が出ている:

data["x+1"] = data["x"].shift(1) 
data["x+2"] = data["x"].shift(2) 

res = data[["x", "x+1", "x+2"]].apply( 
    lambda x : (x[0] + x[2])/2 
      if ((x[0] > 0) and (x[1] <= 0) and (x[2] > 0)) 
      else x[1], axis=1) 

data[x] = res.shift(-1) 

これは、原則的に動作し、私はzip圧縮3上を反復することを好むので、などのデータフレームシフト:

for row1, row2, row3 in zip(data.iterrows(), data.shift(1).iterrows(), data.shift(2).iterrows()): 
     ... 

しかし、これらの方法はどちらも処理するために永遠になります。私はapplyがベクトル化できないこと、そしてメモリに何らかの重複があること(出力)があることを読んだ。私はまた、次のことを試してみたが、それは正しく動作してのちょうど内気だ

data.loc[ data["x"] == 0 , "x" ] = np.NaN 
data["x"].fillna(method="ffill", limit=1, inplace=True) 
data["x"].fillna(0) 

これは超高速ですが、私が何をし、それを望んでいるだろう何をしません(それは単に過ぎて充填を停止します最初のNaNを記入したいのですが、の場合はのみです。

この解決方法をマルチギガバイトのファイルにするにはどうすればよいかわかりません。私は現在awkを使ってファイルを実行しようとしていますが、これは理想的ではありません。なぜなら、コードの維持管理が難しく、他の同様の前処理が既にPythonプログラムで行われているからです。

アドバイスありがとうございます。

答えて

4

あなたはwhere機能でそれをベクトル化することができます入力して

preV = data['x'].shift(1) 
nexT = data['x'].shift(-1) 
data['x'] = data['x'].where((data['x'] > 0) | (preV <= 0) | (nexT <= 0), (preV + nexT)/2) 

data = pd.DataFrame({"x": [1,2,3,0,0,2,3,0,4,2,0,0,0,1]}) 

が与える:

0  1.0 
1  2.0 
2  3.0 
3  0.0 
4  0.0 
5  2.0 
6  3.0 
7  3.5    # 0 gets replaced here 
8  4.0 
9  2.0 
10 0.0 
11 0.0 
12 0.0 
13 1.0 
Name: x, dtype: float64 

それとも示すために、論理的なインデックスを作成することができます位置v以前の行と次の行の平均値を代入する必要があります。

data.loc[(data['x'] <= 0) & (preV > 0) & (nexT > 0), "x"] = (preV + nexT)/2 
+0

素晴らしい答えです。 –

+0

ありがとうございます。うれしい! – Psidom

+0

これは、[この質問](http://stackoverflow.com/questions/32368078/how-do-i-calculate-a-rolling-mean-with-custom-weights-japanese/)のように、カスタムウェイト付きローリング平均を使用します。イン・パンダ/ 32369384#32369384)。あなたは 'preV、nexT'を手作業で計算する必要はなく、最初に述べたようにこれが大きなデータだった場合、それらは大きくなる可能性があります。 – smci

関連する問題