循环,它使用一个函数遍历历史记录中某个时间范围内的观察值,然后将多行写入数据帧

2024-10-01 00:35:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个循环,它将搜索指定的时间范围(使用OSI-PI历史记录中的历史数据),并将多行返回到一个dataframe,其中定义的函数为true,相关的计算已经发生。然后,该数据帧将被写入SQL数据库。你知道吗

我有一种感觉,这应该发生在一个for循环中,使用len遍历观察范围,但我不知道如何编写它。基本上,这个循环应该做的是查看从OSI PI historian中提取的数据的规定时间范围,当函数“Total\ u Oil”中的条件满足时,它应该对totaloil进行计算,然后将答案写入数据帧(df1)中的一行,然后继续查看观察结果(标记为“points”)在代码中),直到再次满足函数的条件,然后重新运行函数的totaloil计算,将答案写入数据帧,并继续这样操作,直到观察结束。我已经包括了一段代码,它可以在整个时间范围内运行函数并进行计算。我将dataframe写入SQL数据库的部分现在被注释掉了,因为我认为如果dataframe中有多行,它应该将它们全部写入SQL(如果我错了,请纠正我),所以我更专注于尝试在dataframe中创建这些多行。(为了节省空间,我省略了import语句)

connStr = pyodbc.connect('DRIVER={SQL Server};SERVER=ServerA;DATABASE=DatabaseA;Trusted_Connection=yes')
cursor = connStr.cursor()

sys.path.append(r'C:\Program Files (x86)\PIPC\AF\PublicAssemblies\4.0')
clr.AddReference('OSIsoft.AFSDK')


piServers = PIServers()
piServer = piServers['PISERVERA']
piServer.Connect(False)

def get_val(tag_name):
            datpoints=PIPoint.FindPIPoint(piServer,tag_name)
            timerange = AFTimeRange("2018-04-07 15:48", "2018-04-08 23:29")
            recorded = datpoints.RecordedValues(timerange, AFBoundaryType.Inside, "", False)
            times = []
            values= []
            points= {}

            for event in recorded:
                        points[str(event.Timestamp.LocalTime)] = int(event.Value)
                        times.append(str(event.Timestamp.LocalTime))
                        values.append(event.Value)
                        pd_df=pd.DataFrame(data={tag_name:values}, index=times)
            return pd_df

pd_df1=get_val('Tag1')
pd_df2=get_val('Tag2')

df=pd.concat([pd_df1, pd_df2], axis=1, sort=True)
final_df = df.assign(server='PISERVERA',SampleType='RAW',Confidence=100)
df.fillna(0, inplace=True)
df['runstattag'] = df['Tag1'].astype(float)
df['oiltag'] = df['Tag2'].astype(float)

def Total_Oil(dframe):
            try:
                        start_row = dframe[(dframe.oiltag > 0) & (dframe.runstattag < 40)].index[0]
                        end_row = dframe[(dframe.oiltag == 0) & (dframe.runstattag > 40) & (dframe.index > start_row)].index[0]
                        subset = dframe[start_row:end_row]
                        totaloil = subset.oiltag.sum()
                        pd_df3=pd.DataFrame(data={'Server':['PISERVERA'],'Tagname':['Boiler_StartOil'],'SampleType':['RAW'],'TimeStamp':end_row,'Value':totaloil,'Confidence':[100]})
            except IndexError:
                        totaloil = 0
                        pd_df3=pd.DataFrame(data={'Server':['PISERVERA'],'Tagname':['Boiler_StartOil'],'SampleType':['RAW'],'TimeStamp':end_row,'Value':totaloil,'Confidence':[100]})
            return pd_df3


df1 = Total_Oil(df)




print('Calculating Total Oil Usage…')

print(df1)

# for index,row in df1.iterrows():
#          cursor.execute("INSERT INTO [DatabaseA].[dbo].[TableA] (Server,Tagname,SampleType,TimeStamp,Value,Confidence) values (?,?,?,?,?,?)",row['Server'],row['Tagname'],row['SampleType'],row['TimeStamp'],row['Value'],row['Confidence'])
#          connStr.commit()
# cursor.close()
# connStr.close()

基本上我希望Total_Oil函数在startrow条件为真时开始,在endrow条件为真时结束,将数据写入dataframe中的一行,然后继续查看观察结果,看看是否存在startrow条件为真的另一个事件,然后再次运行函数对totaloil的计算


Tags: 数据函数eventdataframedfservervalue条件