2014-07-23 1 views
1

숫자 열 및 부울 데이터가 서로 다른 열에 포함 된 큰 시계열 데이터 프레임이 있습니다. 데이터를 1 분 간격에서 15 분 간격으로 다운 샘플링하려고합니다. 부울 열은 시스템 상태이며, 나는 그들을 다운 샘플링하는 방법에 어려움을 겪고 있으며 여전히 모든 오류를 유지합니다. 현재, 내 리 샘플은 last을 사용하므로 마지막 행에서 발생하는 모든 시스템 오류를 간과 할 수 있습니다.리 샘플로 부울 데이터가 포함 된 다운 사이즈 시리즈

내가 뭘하고 싶은지 : 15 분 동안 모든 열에서 '오류'가 발생하면 리샘플링 후의 결과 타임 스탬프는 '오류'를 읽습니다. 그렇지 않으면 '정상'이라고 읽습니다.

솔루션은 resample의 how=''에 있지만, 내가 numpy와 pandas에 익숙하지 않기 때문에 사용할 방법을 알 수 없다는 것을 알고 있습니다.

내 코드 :

import pandas as pd 

# Reads .csv, combines Date and Time columns into Timestamp, sets Timestamp as index 
df = pd.read_csv('data.csv', parse_dates = {'Timestamp' : ['Date', 'Time']}, index_col = 'Timestamp') 

# Fixing any incomplete data and interpolating any numerical gaps 
index = pd.date_range(freq='1min', start=df.first_valid_index(), end=df.last_valid_index()) 
df_clean = df.reindex(set(df.index).union(index)) 
for col in df_clean: 
    df_clean[col] = df_clean[col].interpolate('time').ix[index] 

# Downsampling numerical data 
df_avg = df_clean.resample('15min', how='mean') 

# Downsampling boolean data separately 
df_avg['alarm1']=df_clean['alarm1'].resample('15min', how='last') 

# Fix for missing index name 
df_avg.index.name = 'Timestamp' 

# Adding date and time columns back to dataframe 
df_avg.reset_index(level=0, inplace=True) 
df_avg['Date'] = df_avg['Timestamp'].apply(lambda x: x.strftime('%Y/%m/%d')) 
df_avg['Time'] = df_avg['Timestamp'].apply(lambda x: x.strftime('%H:%M:%S')) 

# Write new .csv 
df_avg[['Date','Time','A','B','C','alarm1']].to_csv('out.csv', index=False) 

답변

2

문서화 문자열은 how 문자열로하라고하지만 사실 그것은 또한 호출 할 수 있습니다.

'alarm1'열이 부울 값인 경우 how=any (또는 how=np.any)을 사용할 수 있습니다. any은 논리적으로 각 시간 빈의 값을 or으로하므로 빈의 값이 True이면 다운 샘플링 된 시리즈의 값은 True가됩니다.

다음은 예입니다.

먼저 임의의 시드를 설정하고 일련의 부울 값을 만듭니다.

In [101]: np.random.seed(123456) 

In [102]: rng = pd.date_range('1/1/2011', periods=25, freq='1min') 

In [103]: ts = pd.Series(np.random.rand(len(rng)) > 0.85, index=rng) 

In [104]: ts 
Out[104]: 
2011-01-01 00:00:00 False 
2011-01-01 00:01:00  True 
2011-01-01 00:02:00 False 
2011-01-01 00:03:00  True 
2011-01-01 00:04:00 False 
2011-01-01 00:05:00 False 
2011-01-01 00:06:00 False 
2011-01-01 00:07:00 False 
2011-01-01 00:08:00 False 
2011-01-01 00:09:00 False 
2011-01-01 00:10:00 False 
2011-01-01 00:11:00 False 
2011-01-01 00:12:00 False 
2011-01-01 00:13:00  True 
2011-01-01 00:14:00 False 
2011-01-01 00:15:00 False 
2011-01-01 00:16:00 False 
2011-01-01 00:17:00 False 
2011-01-01 00:18:00 False 
2011-01-01 00:19:00 False 
2011-01-01 00:20:00  True 
2011-01-01 00:21:00 False 
2011-01-01 00:22:00 False 
2011-01-01 00:23:00 False 
2011-01-01 00:24:00 False 
Freq: T, dtype: bool 

5 분 주파수로 변환하려면 resample을 사용하십시오. 논리적으로 how=np.any을 사용하여 or 시간대의 값을 사용하십시오.

In [105]: ds = ts.resample('5min', how=np.any) 

In [106]: ds 
Out[106]: 
2011-01-01 00:00:00  True 
2011-01-01 00:05:00 False 
2011-01-01 00:10:00  True 
2011-01-01 00:15:00 False 
2011-01-01 00:20:00  True 
Freq: 5T, dtype: bool 
또한 때마다 빈 당신에게 경보의 수를 줄 것이다 값을 요약 할 수

:

In [107]: ts.resample('5min', how=sum) 
Out[107]: 
2011-01-01 00:00:00 2 
2011-01-01 00:05:00 0 
2011-01-01 00:10:00 1 
2011-01-01 00:15:00 0 
2011-01-01 00:20:00 1 
Freq: 5T, dtype: float64 

업데이트 :

코멘트에서 언급 한 바와 같이, 경우 , alarm1 열에는 'YES''NO' 문자열이 포함되어 있습니다. 여러 가지 방법으로 처리 할 수 ​​있습니다. 예를 들어 값을 부울 값 (예 : tsbool = ts == 'YES')으로 변환하고 위의 방법을 사용할 수 있습니다.

또는 사용자 정의 집계 함수를 작성할 수 같은

def func(faults): 
    return 'YES' if np.any(faults == 'YES') else 'NO' 

resamplehow 인수로 제공합니다. 여기에 예제가 있습니다.

먼저 'YES'및 'NO'문자열이 포함 된 시리즈를 만듭니다.

In [60]: rng = pd.date_range('1/1/2011', periods=25, freq='1min') 

In [61]: yn = np.array(['NO', 'YES']) 

In [62]: ts = pd.Series(yn[(np.random.rand(len(rng)) > 0.85).astype(int)], index=rng) 

In [63]: ts 
Out[63]: 
2011-01-01 00:00:00  NO 
2011-01-01 00:01:00  NO 
2011-01-01 00:02:00  NO 
2011-01-01 00:03:00  NO 
2011-01-01 00:04:00 YES 
2011-01-01 00:05:00 YES 
2011-01-01 00:06:00  NO 
2011-01-01 00:07:00 YES 
2011-01-01 00:08:00  NO 
2011-01-01 00:09:00  NO 
2011-01-01 00:10:00  NO 
2011-01-01 00:11:00  NO 
2011-01-01 00:12:00  NO 
2011-01-01 00:13:00  NO 
2011-01-01 00:14:00  NO 
2011-01-01 00:15:00  NO 
2011-01-01 00:16:00 YES 
2011-01-01 00:17:00  NO 
2011-01-01 00:18:00  NO 
2011-01-01 00:19:00  NO 
2011-01-01 00:20:00  NO 
2011-01-01 00:21:00  NO 
2011-01-01 00:22:00  NO 
2011-01-01 00:23:00  NO 
2011-01-01 00:24:00  NO 
Freq: T, dtype: object 

'YES'및 'NO'문자열의 배열을 단일 문자열로 줄이는 함수를 정의하십시오.

In [64]: def func(alarms): 
    ....:  return 'YES' if np.any(alarms == 'YES') else 'NO' 
    ....: 

ts를 리샘플링 기능을 사용합니다.

In [65]: ds = ts.resample('5min', how=func) 

In [66]: ds 
Out[66]: 
2011-01-01 00:00:00 YES 
2011-01-01 00:05:00 YES 
2011-01-01 00:10:00  NO 
2011-01-01 00:15:00 YES 
2011-01-01 00:20:00  NO 
Freq: 5T, dtype: object 
+0

내가 잘못 본 것 같습니다. 내 결함 열에는 YES/NO 데이터가 들어 있는데 파이썬은 부울로 간주하지 않습니다. t/f 대신 y/n을 사용하여 오류 열을 구문 분석 할 수 있습니까? – rwester

+0

@rwester : 답변을 업데이트했습니다. –

+0

새로운 기능을 정의했으며 효과가 좋습니다! 고맙습니다! – rwester

관련 문제