pandasdataframe列中变长模式的检测

时间序列索引dataframe的最后2列标识开始('A'或'AA'或'AAA'),结束('F'或'FF'或'FFF')和持续时间(开始和结束之间的行数)的一个物理过程,他们看起来像这样:

在这里输入图像说明

AF序列或它们之间的n个序列长度可变。

我怎样才能识别这些模式,并为他们每个人计算相应行的其他列的平均值?

我非常非常想做的是:

import pandas as pd import xlrd ##### EXCEL LOAD filepath= 'H:\\CCGT GE startup.xlsx' df = pd.read_excel(filepath,sheet_name='Sheet1',header=0,skiprows=0,parse_cols='A:CO',index_col=0) df = df.sort_index() # set increasing time index, source data is time decreasing gas=[] for i,row in df.iterrows(): if df['FLAG STARTUP TG1'] is not 'n': while 'F' not in df['FLAG STARTUP TG1']: gas.append(df['PORTATA GREZZA TG1 - m3/h']) gas.append(i) 

但脚本卡在第一个if(不符合'n'条件,并继续追加同一行,我配对)。 另外,我的方法在排除最后一个仍然属于同一个进程的'F'行也是错误的,应该被视为它的一部分!

PS第一千行df在这里http://www.filedropper.com/ccgtgestartup1000

pps除了不工作,我的方法也是排除最后的'F'行仍然属于相同的过程,也应该被视为其中的一部分是错误的!

ppps 2列是指2个不同的进程/机器,并且是不相关的(几乎在后面会有更多的介绍),我想对两者进行相同的分析(他们会参考不同列的平均值)。 第一个“A”string表示进程的开始,并重复,直到最后一个用'F'string标记的时间戳。 在原始文件中,时间戳降序,这就是为什么我使用sort_index()方法。 string长度取决于其他列的值,但明显的FLAG列相关性仅在3个字符的string“AAA”和“FFF”中,因为只有在2个进程以+ 1个时间戳开始时才会发生。

这是我如何设法得到所需的结果(注意我后来决定只有单个字符'A' – >'F'序列是感兴趣的)

 import pandas as pd import numpy as np ##### EXCEL LOAD filepath= 'H:\\CCGT GE startup.xlsx' df = pd.read_excel(filepath,sheet_name='Sheet1',header=0,skiprows=0,parse_cols='A:CO',index_col=0) df = df.sort_index() # set increasing time index, source data is time decreasing tg1 = pd.DataFrame(index=df.index.copy(),columns=['counter','flag','gas','p','raw_p','tv_p','lhv','fs']) k = 0 for i,row in df.iterrows(): if 'A' == str(row['FLAG STARTUP TG1']): tg1.ix[i,'flag']=row['FLAG STARTUP TG1'] tg1.ix[i,'gas']=row['Portata gas naturale'] tg1.ix[i,'counter']=k tg1.ix[i,'fs']=row['1FIRED START COUNT - N°'] tg1.ix[i,'p']=row['POTENZA ATTIVA MONTANTE 1 SU 400 KV - MW'] tg1.ix[i,'raw_p']=row['POTENZA ATTIVA MONTANTE 1 SU 15 KV - MW'] tg1.ix[i,'tv_p']=row['POTENZA ATTIVA MONTANTE TV - MW'] tg1.ix[i,'lhv']=row['LHV - MJ/Sm3'] elif 'F' == str(row['FLAG STARTUP TG1']): tg1.ix[i,'flag']=row['FLAG STARTUP TG1'] tg1.ix[i,'gas']=row['Portata gas naturale'] tg1.ix[i,'counter']=k tg1.ix[i,'fs']=row['1FIRED START COUNT - N°'] tg1.ix[i,'p']=row['POTENZA ATTIVA MONTANTE 1 SU 400 KV - MW'] tg1.ix[i,'raw_p']=row['POTENZA ATTIVA MONTANTE 1 SU 15 KV - MW'] tg1.ix[i,'tv_p']=row['POTENZA ATTIVA MONTANTE TV - MW'] tg1.ix[i,'lhv']=row['LHV - MJ/Sm3'] k+=1 tg1 = tg1.dropna(axis=0) tg1 = tg1[tg1['gas'] != 0] #data where gas flow measurement is missing is dropped tg1 = tg1.convert_objects(convert_numeric=True) #timestamp count for each startup for duration calculation counts = pd.DataFrame(tg1['counter'].value_counts(),columns=['duration']) counts['start']=counts.index counts = counts.set_index(np.arange(len(tg1['counter'].value_counts()))) tg1 = tg1.merge(counts,how='inner',left_on='counter',right_on='start') # filter out non pertinent startups (too long or too short) tg1 = tg1[tg1['duration'].isin([6,7])] #calculate thermal input per start (process) table = tg1.groupby(['counter']).mean() table['t_in']=table.apply((lambda row: row['gas']*row['duration']*0.25*row['lhv']/3600),axis=1) 

任何改进和build议,在迭代中进行计算,并在欢迎之后避免所有“准备工作”。