2015-08-13 4 views
1

Это сообщение длительное время, и я буду очень благодарен всем, кто читает его до конца. :)Алгоритм оптимизации Python Pandas: сравнить дату и время получения

Я экспериментирую с выполнением проблем с кодом python и хотел бы знать, есть ли у вас лучший способ делать то, что я хочу. Я объясняю свою проблему в брифинге. У меня много измерений солнечных батарей. Каждый из них выполняется каждые 3 минуты. К сожалению, некоторые измерения могут потерпеть неудачу. Цель состоит в том, чтобы сравнить время, чтобы сохранить только те значения, которые были измерены в те же минуты, а затем получить их. Графический интерфейс также включен в мое программное обеспечение, поэтому каждый раз, когда пользователь меняет панели для сравнения, расчет должен быть выполнен снова. Для этого я реализовал две части, первая из которых создает каждую из них каждую секунду каждую секунду, а вторая сравнивает предыдущий вектор и сохраняет только общие меры.

Все данные содержатся в pandas df energiesDatas. Соответствующие столбцы:

  • имя: содержит имя панели (длина 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) 

На самом деле эта часть занимает очень много времени.

Мой вопрос: есть ли способ сэкономить время, используя встроенную функцию или что-то еще.

Большое спасибо

Kilian

+0

Не могли бы вы попытаться уменьшить сложность вашего примера? Возможно, покажите подмножество соответствующих данных для этого шага, который занимает много времени? –

+0

@ chris-sc Уважаемый Крис, спасибо за ваше внимание. Я знаю, что это немного. Вот ссылка на пример: http: //s27.postimg.org/w2wb7ricj/example_python_stackoverlfow.png Извините, но я не могу загрузить изображение на сообщение еще –

+0

@ chris-sc и вот 1-я часть, описанная выше, http: //s4.postimg.org/rxrr7dusd/example_python_stackoverlfow2.png. Вторая часть принимает list_comp для желаемых панелей, умножает их, а затем извлекает соответствующие данные (под этим я подразумеваю соответствующую дату) из исходного фрейма.Эта часть занимает много времени, потому что она перебирает все значение и проверяет, есть ли 1 или 0. Еще раз спасибо –

ответ

0

Ответ CHRIS-SC sloved мою проблему:

Я считаю, ваша структура данных не подходит для вашей проблемы. Особенно список в полях DataFrame, они делают петли или применяются почти неизбежно. Могли бы вы в принципе переструктурировать данные? (Например, один df на солнечную панель со столбцами дата, время, энергия)