如何让我的 for 循环 python 函数更快

问题描述 投票:0回答:1

问题 - 我有一个 python 函数,它从 excel 表中读取值并进行计算,计算后我的值正在使用 xlwings 包写回 excel 表。为了写回值,我创建了一个循环函数,它将遍历 pandas 数据框并将值写回列中的 excel。

数据框看起来像这样
Dataframe looks like this

def write_matrixdata_SOCs_to_excel(self,number_of_SOCs, Profit_calculator_matrix_result: pd.DataFrame):
        """
        This function will write results from profit calculator with 2 SOCs & 12 SOCs to peak shave excel.

        For Example : Peakshave_Reader.Writing_matrix_data_2SOCs_to_excel(excel_workbook,Number_of_SOCs,Output_result_data)
        """
        app = xw.App(visible=False)
        WorkBook = xw.Book(self.file_path, update_links=False) # WorkBook = xw.Book(filename) would open an existing file
        WorkBook.app.screen_updating = False
        Working_Sheet = WorkBook.sheets["Wirtschaftlichkeitsmatrix"] # activating working sheet 
        if number_of_SOCs == 2:
            for column_letter in range (ord('C'),ord('M')):
                for row_number in range (4,53,12):
                #for row 1 c_rate 0.25
                    if Profit_calculator_matrix_result.columns.isin([(Working_Sheet[str(chr(column_letter))+'2'].value)*1000]).any() and Profit_calculator_matrix_result.index.isin([Working_Sheet['A'+str(row_number)].value]).any() == True: #to verify the column is present in profit calculator sim output dataframe, if not then next steps will skip and no data will write for this column #to verify the column is present in profit calculator sim output dataframe, if not then next steps will skip and no data will write for this column
                        if type(Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number)].value)]) == pd.DataFrame: # if the column is present but values is 0 (NOT A DATAFRAME) because of no battery cost present in investtable, then below step will skip, and no data will write for that column
                            Working_Sheet.range(str(chr(column_letter))+str(row_number)+':'+str(chr(column_letter))+str(row_number+11)).options(index=False,header=False).value = Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number)].value)]
                            Working_Sheet[str(chr(column_letter))+str(row_number)+':'+str(chr(column_letter))+str(row_number+11)].color = (96,191,176) 
                        else:
                            logging.warning('column with '+ str((Working_Sheet[str(chr(column_letter))+'2'].value))+ ' & index with '+ str(Working_Sheet['A'+str(row_number)].value) + ' is not a dataframe, there are no battery cost present in Investtabelle')
                    else:
                        logging.warning('column with '+ str((Working_Sheet[str(chr(column_letter))+'2'].value))+ ' & index with '+ str(Working_Sheet['A'+str(row_number)].value) + ' is not present in dataframe, i.e nicht berechnen')
        else:
            for column_letter in range (ord('C'),ord('M')):
                for row_number_matrix in range (4,53,12):
                    if Profit_calculator_matrix_result.columns.isin([(Working_Sheet[str(chr(column_letter))+'2'].value)*1000]).any() and Profit_calculator_matrix_result.index.isin([Working_Sheet['A'+str(row_number_matrix)].value]).any() == True: #to verify the column is present in profit calculator sim output dataframe, if not then next steps will skip and no data will write for this column
                        if type(Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number_matrix)].value)]) == pd.DataFrame: # if the column is present but values is 0 (NOT A DATAFRAME) because of no battery cost present in investtable, then below step will skip, and no data will write for that column
                            without_12Soc_and_Pmax = (Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number_matrix)].value)]).drop(['Soll-SOC 1-12','Pmax Netzbeladung 1-12','Reserve-SOC 1-12']) # dropping 'Soll-SOC 1-12','Pmax Netzbeladung 1-12','Reserve-SOC 1-12' because values are numpy.ndarray values and values can not be written in single cells, these values will be going in 12soc and Pmax table
                            Working_Sheet.range(str(chr(column_letter))+str(row_number_matrix)+':'+str(chr(column_letter))+str(row_number_matrix+11)).options(index=False,header=False).value = without_12Soc_and_Pmax # dataframe with 12 soc and Pmax, which will be write in main matrix table 
                            Working_Sheet[str(chr(column_letter))+str(row_number_matrix)+':'+str(chr(column_letter))+str(row_number_matrix+11)].color = (96,191,176)
                            Working_Sheet.range(str(chr(column_letter))+str(row_number_matrix+78)+':'+str(chr(column_letter))+str(row_number_matrix+89)).options(index=False,header=False).value = pd.DataFrame((Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number_matrix)].value)]).at['Soll-SOC 1-12',0]) # writing 12 soc in table, adding number +78 and +89 for adjusting cell number for 12soc matrix table 
                            Working_Sheet[str(chr(column_letter))+str(row_number_matrix+78)+':'+str(chr(column_letter))+str(row_number_matrix+89)].color = (96,191,176)
                            Working_Sheet.range(str(chr(column_letter))+str(row_number_matrix+147)+':'+str(chr(column_letter))+str(row_number_matrix+158)).options(index=False,header=False).value = pd.DataFrame((Profit_calculator_matrix_result[(Working_Sheet[str(chr(column_letter))+'2'].value)*1000][(Working_Sheet['A'+str(row_number_matrix)].value)]).at['Pmax Netzbeladung 1-12',0])/1000 # writing 12 Pmax values in table, adding number +147 and +158 for adjusting cell number for 12soc matrix table 
                            Working_Sheet[str(chr(column_letter))+str(row_number_matrix+147)+':'+str(chr(column_letter))+str(row_number_matrix+158)].color = (96,191,176)
                        else:
                            logging.warning('column with '+ str((Working_Sheet[str(chr(column_letter))+'2'].value)*1000)+ ' & index with '+ str(Working_Sheet['A'+str(row_number_matrix)].value) + ' is not a dataframe, there are no battery cost present in Investtabelle')
                    else:
                        logging.warning('column with '+ str((Working_Sheet[str(chr(column_letter))+'2'].value)*1000)+ ' & index with '+ str(Working_Sheet['A'+str(row_number_matrix)].value) + ' is not present in dataframe, i.e nicht berechnen')
        WorkBook.save()
        WorkBook.app.screen_updating = True
        app.quit()

输出结果到excel表(循环就是这样把数据写回excel)
loop is writing data back to excel like this

需要解决方案 = 我的函数需要 3 分半钟来写这些值,我怎样才能减少时间并使我的循环函数更快。

python excel for-loop xlwings
1个回答
0
投票

我尝试通过使用列表理解和实例来优化代码,但它仍然需要时间来编写。

def write_matrixdata_SOCs_to_excel(self, number_of_SOCs, Profit_calculator_matrix_result: pd.DataFrame):
    """
    This function will write results from profit calculator with 2 SOCs & 12 SOCs to peak shave excel.

    For Example : Peakshave_Reader.Writing_matrix_data_2SOCs_to_excel(excel_workbook,Number_of_SOCs,Output_result_data)
    """
    WorkBook = xw.Book(self.file_path)
    Working_Sheet = WorkBook.sheets["Wirtschaftlichkeitsmatrix"]
        
    # Use list comprehension to generate a list of row numbers
    row_numbers = [4 + 12 * i for i in range(5)]
    
    
    for column_letter in range(ord('C'), ord('M')):
        column_value = int((Working_Sheet[str(chr(column_letter)) + '2'].value*1000))
        if column_value in Profit_calculator_matrix_result.columns:
            for row_number in row_numbers:
                row_value = Working_Sheet['A' + str(row_number)].value
                if row_value in Profit_calculator_matrix_result.index:
                    data = Profit_calculator_matrix_result[column_value][row_value]
                    if isinstance(data, pd.DataFrame):
                        without_12Soc_and_Pmax = data.drop(['Soll-SOC 1-12', 'Pmax Netzbeladung 1-12', 'Reserve-SOC 1-12'])
                        Working_Sheet.range(str(chr(column_letter)) + str(row_number) + ':' + str(chr(column_letter)) + str(row_number + 11)).options(index=False, header=False).value = without_12Soc_and_Pmax
                        Working_Sheet[str(chr(column_letter)) + str(row_number) + ':' + str(chr(column_letter)) + str(row_number + 11)].color = (96, 191, 176)
                        Working_Sheet.range(str(chr(column_letter)) + str(row_number + 78) + ':' + str(chr(column_letter)) + str(row_number + 89)).options(index=False, header=False).value = pd.DataFrame(data.at['Soll-SOC 1-12', 0])
                        Working_Sheet[str(chr(column_letter)) + str(row_number + 78) + ':' + str(chr(column_letter)) + str(row_number + 89)].color = (96, 191, 176)
                        Working_Sheet.range(str(chr(column_letter)) + str(row_number + 147) + ':' + str(chr(column_letter)) + str(row_number + 158)).options(index=False, header=False).value = pd.DataFrame(data.at['Pmax Netzbeladung 1-12', 0]) / 1000
                        Working_Sheet[str(chr(column_letter)) + str(row_number + 147) + ':' + str(chr(column_letter)) + str(row_number + 158)].color = (96, 191, 176)

© www.soinside.com 2019 - 2024. All rights reserved.