2017-10-13 3 views
2

우려의 이전 N 열의 합이 실시 팬더 dataframe 인 측정. Valid 열이 True 인 경우 측정이 유효한 것으로 간주됩니다. 그럼 위의 dataframe의 두 가지 예를 사용하여 명확히하자조건부 평균 및 팬더 dataframe

  1. Index 3을 : 지수가 2,1,0 사용되어야한다. 예상 됨 Sum = 9.0, Mean = 3.0
  2. Index 7 : 색인 7,6,5을 사용해야합니다. 예상 됨 Sum = 6.0, Mean = 2.0

pandas.rolling을 시도하고 새로운 이동 된 열을 만들었지 만 성공하지 못했습니다. 내 검사 (직접 실행해야 함)에서 발췌 한 내용을 참조하십시오.

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) 

모든 도움이나 해결책을 제공해 주시면 대단히 감사하겠습니다. 감사와 환호!

편집 : 명확한 설명은 :

 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을 : 다른 설명 :이 결과 dataframe 내가 기대입니다

내가 참으로 잘못 계산하지 않았다, 그러나 오히려 내가 아니라 내 의도가 명확하지 않았다 가질 수있다. Trigger 열에서

Desired dataframe, relevant fields highlighted

것을 우선 보자 : 여기에 같은 dataframe을 사용하여 다른 시도이다 우리는 지수 3 (녹색 사각형)의 첫 번째 True를 찾을 수 있습니다. 그래서 색인 3이 우리가보기 시작하는 지점입니다. 인덱스 3에는 유효한 측정 값이 없습니다 (열 ValidFalse, 빨간색 직사각형). 그래서 우리는 세 줄을 축적 할 때까지 시간이 흘러 가기 시작합니다. 여기서 ValidTrue입니다. 이 인덱스 2,1- 이들 세 가지 지표를 들면 0. 발생 우리 합을 계산하고 열 Measurement (청색 사각형)의 의미 :

  • SUM : 2.0 + 4.0 + 3.0 = 9.0
  • MEAN : Trigger 열에서 다음 True 다시 봐 : (2.0 + 4.0 + 3.0)/3 =

3.0 이제 우리는이 작은 알고리즘의 다음 반복을 시작합니다. 색인 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

가 Heres는 옵션, 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 

편집에 동일 거짓으로 설정, reflec로 업데이트 됨 t 유효한 인수

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

원본 게시물에서 두 번째 편집을보십시오. – bolla