2016-10-31 5 views
0

나는 가장 큰 적분, 즉 부호가 바뀌기 전에 가장 긴 적분을 찾을 필요가있는 진동하는 시계열 데이터를 가지고 있습니다. 이 방법파이썬으로 시계열에서 가장 큰 N 적분을 찾기

import pandas as pd 
import numpy as np 
from itertools import tee 


def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return zip(a, b) 

asign = np.sign(df['c']) 
signchange = ((np.roll(asign, 1) - asign) != 0).astype(int) 

changes = list(signchange[signchange>0].index) 
changes.insert(0, 0) 
changes.append(list(df[' timestamp'].index)[-1]) 


integral_borders = list(pairwise(changes)) 


integrals = [] 

for (begin, end) in integral_borders: 
    area = np.trapz(df['c'][begin:end]) 
    integrals.append((area, (begin, end))) 

# this gives 
# In [67]: integrals 
# Out[67]: [(24.0, (0, 9)), (-6.0, (9, 13)), (1.5, (13, 15))] 

내 문제는 그것이 계산 비용이 있다는 것입니다 :

여기
In [166]: df 
Out[166]: 
    c timestamp 
0 1   1 
1 2   2 
2 3   3 
3 4   4 
4 5   5 
5 4   6 
6 3   7 
7 2   8 
8 1   9 
9 -1   10 
10 -2   11 
11 -3   12 
12 -1   13 
13 1   14 
14 2   15 
15 3   16 

내가 지금 적분을 찾는 방법입니다 : 여기 편의를 위해 예입니다. 한 번에 전체 데이터 파일을 읽을 필요가 없도록 개선하고 싶습니다. 또한 단순한 경우 append이 단순한 인서트 정렬 일 수도 있지만, 작은 N 개의 인티그레이션 만 유지하는 것이 좋습니다.

둘 다 할 수있는 방법을 지적 할 수 있습니까?

답변

2

찾고 계신 분은 groupby입니다. 팬더에서 사전 프로세싱 일 :

df['change'] = df['c'].shift() * df['c'] < 0 
df['group'] = df['change'].cumsum() 

결과 :

df.groupby('group')['c'].apply(np.trapz) 

결과 :

0 24.0 
1 -6.0 
2  4.0 

c timestamp change group 
0 1   1 False  0 
1 2   2 False  0 
2 3   3 False  0 
3 4   4 False  0 
4 5   5 False  0 
5 4   6 False  0 
6 3   7 False  0 
7 2   8 False  0 
8 1   9 False  0 
9 -1   10 True  1 
10 -2   11 False  1 
11 -3   12 False  1 
12 -1   13 False  1 
13 1   14 True  2 
14 2   15 False  2 
15 3   16 False  2 

나서 별도로 각 그룹에 np.trapz 함수를 적용 수정 : 각 기간의 시작과 끝을 복구하려면 firstlast groupby 메소드를 사용할 수 있습니다.

df.groupby('group')['timestamp'].first() 
df.groupby('group')['timestamp'].last() 

당신이 한 번에 세 가지 기능을 적용 할 경우

, 당신은 agg를 사용할 수 있습니다 놀라운

df.groupby('group').agg({ 
    'c': np.trapz, 
    'timestamp': ['first', 'last'] 
}) 
+0

을! 이것은 매우 우아합니다! – Oz123

+0

팬더는 꽤 우아 할 수 있습니다. 어떤 사람들은 그것을 pandorable이라고 부릅니다.) – IanS

+0

그러나 결과의 출력은 내게 적분만을 제공합니다. 나는 각 intgral의 시작과 끝을 가지고 싶다 – Oz123