2017-10-13 7 views
2

憂慮がこの典型的なパンダのデータフレームである:条件付き平均と合計

 Measurement Trigger Valid 
    0   2.0 False True 
    1   4.0 False True 
    2   3.0 False True 
    3   0.0  True False 
    4  100.0 False True 
    5   3.0 False True 
    6   2.0 False True 
    7   1.0  True True 

TriggerTrueあるたびに、私は(現在から開始)の和を計算し、最後の3の意味を希望する有効な測定値。 Validの列がTrueの場合、有効と見なされます。それでは、上記のデータフレームにおける2つの例を使用して明確にしましょう:

  1. Index 3:インデックス2,1,0を使用する必要があります。予想されるSum = 9.0, Mean = 3.0
  2. Index 7:指標7,6,5を使用する必要があります。私はpandas.rollingを試してみましたが、新たに作成しているSum = 6.0, Mean = 2.0

を期待し、列をシフトしたが、成功しませんでした。

import unittest 
import pandas as pd 
import numpy as np 
from pandas.util.testing import assert_series_equal 

def create_sample_dataframe_2(): 
    df = pd.DataFrame(
     {"Measurement" : [2.0, 4.0, 3.0, 0.0, 100.0, 3.0, 2.0, 1.0 ], 
     "Valid"  : [True, True, True, False, True, True, True, True], 
     "Trigger"  : [False, False, False, True, False, False, False, True], 
     }) 
    return df 

def expected_result(): 
    return pd.DataFrame({"Sum" : [np.nan, np.nan, np.nan, 9.0, np.nan, np.nan, np.nan, 6.0], 
         "Mean" :[np.nan, np.nan, np.nan, 3.0, np.nan, np.nan, np.nan, 2.0]}) 

class Data_Preparation_Functions(unittest.TestCase): 

    def test_backsummation(self): 
     N_SUMMANDS = 3 
     temp_vars = [] 

     df = create_sample_dataframe_2() 
     for i in range(0,N_SUMMANDS): 
      temp_var = "M_{0}".format(i) 
      df[temp_var] = df["Measurement"].shift(i) 
      temp_vars.append(temp_var) 

     df["Sum"] = df[temp_vars].sum(axis=1) 
     df["Mean"] = df[temp_vars].mean(axis=1) 
     df.loc[(df["Trigger"]==False), "Sum"] = np.nan 
     df.loc[(df["Trigger"]==False), "Mean"] = np.nan 

     assert_series_equal(expected_result()["Sum"],df["Sum"]) 
     assert_series_equal(expected_result()["Mean"],df["Mean"]) 

    def test_rolling(self): 
     df = create_sample_dataframe_2() 
     df["Sum"] = df[(df["Valid"] == True)]["Measurement"].rolling(window=3).sum() 
     df["Mean"] = df[(df["Valid"] == True)]["Measurement"].rolling(window=3).mean() 

     df.loc[(df["Trigger"]==False), "Sum"] = np.nan 
     df.loc[(df["Trigger"]==False), "Mean"] = np.nan 
     assert_series_equal(expected_result()["Sum"],df["Sum"]) 
     assert_series_equal(expected_result()["Mean"],df["Mean"]) 


if __name__ == '__main__': 
    suite = unittest.TestLoader().loadTestsFromTestCase(Data_Preparation_Functions) 
    unittest.TextTestRunner(verbosity=2).run(suite) 

すべてのヘルプやソリューションが大幅に高く評価されています(直接実行する必要があります)私のテストからの抜粋を参照してください。感謝と乾杯!

EDIT:明確化:

 Measurement Trigger Valid Sum Mean 
    0   2.0 False True NaN NaN 
    1   4.0 False True NaN NaN 
    2   3.0 False True NaN NaN 
    3   0.0  True False 9.0 3.0 
    4  100.0 False True NaN NaN 
    5   3.0 False True NaN NaN 
    6   2.0 False True NaN NaN 
    7   1.0  True True 6.0 2.0 

はEDIT2:もう一つの明確化:これは私が期待したデータフレームである

私は確かに誤って計算していないのではなく、私は私のように私の意図は明らかなようにしませんでした可能性があります。 Trigger列で

Desired dataframe, relevant fields highlighted

みましょう最初のを見て:ここでは、別のは、同じデータフレームを使用してみます私たちは、インデックス3(緑の四角形)で最初Trueを見つけます。だから、インデックス3がポイントであり、ここで我々は見始める。インデックス3に有効な測定値がありません(列ValidFalse、赤い長方形です)。だから、私たちは3行を積み重ねるまで、さらに時間を追って行きます。ここで、ValidTrueです。これは、インデックス2,1とこれら三つのインデックスの0の起こり、我々は和を計算し、カラムMeasurement(青い四角形)の平均:

  • SUM:2.0 + 4.0 + 3.0 = 9.0
  • MEAN。 (2.0 + 4.0 + 3.0)/ 3 = 3.0

今、私たちはこの小さなアルゴリズムの次の繰り返しを開始:Trigger列の次のTrueのためにもう一度見て。インデックス7(緑色の四角形)にあります。インデックス7にも有効な尺度があるので、今回はそれを含めます。私たちの計算のために、私たちはインデックス7,6及び5を使用します(緑の四角形)、およびこれを取得:

  • SUM:1.0 + 2.0 + 3.0 = 6.0
  • MEAN:(1.0 + 2.0 + 3.0)/ 3 = 2.0

これは、この小さな問題にもっと光を当てることを望みます。

+0

が、私はこのような質問を見てきた、基本的にCUMSUMを検出することである、私は今それを見つけるために行きます! – ileadall42

答えて

1

が相続オプション、3時間ローリング平均を取ると、合計

df['RollM'] = df.Measurement.rolling(window=3,min_periods=0).mean() 

df['RollS'] = df.Measurement.rolling(window=3,min_periods=0).sum() 

今のトリガーがNaN

df.loc[df.Trigger == False,['RollS','RollM']] = np.nan 

利回り

Measurement Trigger Valid  RollM RollS 
0   2.0 False True  NaN NaN 
1   4.0 False True  NaN NaN 
2   3.0 False True  NaN NaN 
3   0.0  True False 2.333333 7.0 
4  100.0 False True  NaN NaN 
5   3.0 False True  NaN NaN 
6   2.0 False True  NaN NaN 
7   1.0  True True 2.000000 6.0 

編集に等しいFalseに設定し、 reflecに更新されましたトン有効な引数

df['mean'],df['sum'] = np.nan,np.nan 

roller = df.Measurement.rolling(window=3,min_periods=0).agg(['mean','sum']) 

df.loc[(df.Trigger == True) & (df.Valid == True),['mean','sum']] = roller 

df.loc[(df.Trigger == True) & (df.Valid == False),['mean','sum']] = roller.shift(1) 

利回り

Measurement Trigger Valid mean sum 
0   2.0 False True NaN NaN 
1   4.0 False True NaN NaN 
2   3.0 False True NaN NaN 
3   0.0  True False 3.0 9.0 
4  100.0 False True NaN NaN 
5   3.0 False True NaN NaN 
6   2.0 False True NaN NaN 
7   1.0  True True 2.0 6.0 
+0

これは私が探しているものではありません。明確にするために、私は元の投稿に表形式で期待される結果を追加しました。 – bolla

+0

これがどのように間違っているかをさらに説明できますか?これは、インデックス3の数字を除いて、あなたのサンプルと一致します。私はあなたがそれらを計算していないと信じて、現在の値を含まない、前の3つを行いました@bolla – DJK

+0

私の元の投稿で2番目の編集を見てください。 – bolla