【发布时间】:2015-08-18 15:42:53
【问题描述】:
这篇文章很长,我将非常感谢所有阅读到最后的人。 :)
我正在尝试执行 python 代码问题,想知道您是否有更好的方法来做我想做的事。 我简要地解释了我的问题。我有很多太阳能电池板的测量值。每一项每 3 分钟完成一次。不幸的是,一些测量可能会失败。目标是比较时间,以便仅保留在同一分钟内测量的值,然后检索它们。我的软件中还包含一个 GUI,因此每次用户更改面板进行比较时,都必须重新进行计算。为此,我实现了 2 个部分,第一个为每分钟为每个面板创建一个真或假向量,第二个比较前一个向量并仅保留常用度量。
所有数据都包含在 pandas df energiesDatas 中。相关栏目是:
- name:包含面板的名称(长度为 1)
- 日期:包含测量日期(长度为 1)
- list_time:包含一天中所有测量时间的列表(长度N)
- list_energy_prod : 包含相应的度量(长度 N)
第一部分循环从测量开始到结束的所有可能分钟。如果测量已经完成,则添加 True,否则添加 False。
self.ListCompare2=pd.DataFrame()
for n in self.NameList:#loop over all my solar panels
m=self.energiesDatas[self.energiesDatas['Name']==n]#all datas
#table_date contains all the possible date from the 1st measure, with interval of 1 min.
table_list=[1 for i in range(len(table_date))]
pointerDate=0 #pointer to the current value of time
#all the measures of a given day are transform into a str of hour-minutes
DateString=[b.strftime('%H-%M') for b in m['list_time'].iloc[pointerDate] ]
#some test
changeDate=0
count=0
#store the current pointed date
m_date=m['Date'].iloc[pointerDate]
#for all possible time
for curr_date in table_date:
#if considered date is bigger, move pointer to next day
while curr_date.date()>m_date:
pointerDate+=1
changeDate=1
m_date=m['Date'].iloc[pointerDate]
#if the day is changed, recalculate the measures of this new day
if changeDate:
DateString=[b.strftime('%H-%M') for b in m['list_time'].iloc[pointerDate] ]
changeDate=0
#check if a measure has been done at the considered time
table_list[count]=curr_date.strftime('%H-%M') in DateString
count+=1
#add to a dataframe
self.ListCompare2[n]=table_list
l2=self.ListCompare2
第二部分如下:给定要比较的模块“ListOfName”,检查它们是否在同一时间测量,并且只保持在同一分钟内测量的值。
ListToKeep=self.ListCompare2[ListOfName[0]]#take list of True or False done before
for i in ListOfName[1:]#for each other panels, check if True too
ListToKeep=ListToKeep&self.ListCompare2[i]
for i in ListOfName:#for each module, recover values
tmp=self.energiesDatas[self.energiesDatas['Name']==i]
count=0
#loop over value we want to keep (also energy produced and the interval of time)
for j,k,l,m,n in zip(tmp['list_time'],tmp['Date'],tmp['list_energy_prod'],tmp['list_energy_rec'],tmp['list_interval']):
#calculation of the index
delta_day=(k-self.dt.date()).days*(18*60)
#if the value of ListToKeep corresponding to the index is True, we keep the value
tmp['list_energy_prod'].iloc[count]=[ l[index] for index,a in enumerate(j) if ListToKeep.iloc[delta_day+(a.hour-4)*60+a.minute]==True]
tmp['list_energy_rec'].iloc[count]=[ m[index] for index,a in enumerate(j) if ListToKeep.iloc[delta_day+(a.hour-4)*60+a.minute]==True]
tmp['list_interval'].iloc[count]=[ n[index] for index,a in enumerate(j) if ListToKeep.iloc[delta_day+(a.hour-4)*60+a.minute]==True]
count+=1
self.store_compare=self.store_compare.append(tmp)
其实这部分是需要很长时间的。
我的问题是:有没有办法节省时间,使用内置函数或任何东西。
非常感谢
基连
【问题讨论】:
-
您能尝试降低示例的复杂性吗?也许显示需要很长时间的步骤的相关数据子集?
-
@chris-sc 亲爱的克里斯,感谢您的考虑。我知道这有点。这是一个示例的链接:s27.postimg.org/w2wb7ricj/example_python_stackoverlfow.png 抱歉,我还不能在帖子上上传图片
-
@chris-sc 这是上面描述的第一部分,s4.postimg.org/rxrr7dusd/example_python_stackoverlfow2.png。第二部分将 list_comp 用于所需的面板,将它们相乘,然后从原始数据框中提取相应的数据(我的意思是相应的日期)。这部分需要很多时间,因为它会遍历所有值并检查是否有 1 或 0。再次感谢您
-
我相信您的数据结构不适合您的问题。尤其是
DataFrame字段中的list,它们使循环或apply几乎不可避免。您原则上可以重新构建数据吗? (例如,每块太阳能电池板一个df,列date、time、energy) -
@chris-sc 是的,我可以轻松做到这一点。您是否认为 for 循环会大大降低软件速度?这将改变我的一些代码。我会尝试一下,并在完成后立即通知您。谢谢
标签: python algorithm optimization pandas