如何从iterrows内循环索引处继续执行外层循环?
问题描述
我遇到一个问题,希望在外层循环中从内循环停止的索引位置继续执行代码,当前使用的是同一个DataFrame,请问是否有其他实现方法?
用户提供的现有代码:
def create_freights(self): self.connect_sap() self.file = self.txt_file.text() data = pd.read_excel(self.file) data.columns = data.columns.str.replace(" ",'_') index_2 = 0 for index, row in data[index_2:].iterrows(): if row.FreightType =="y601" or row.FreightType =="Y601" : self.session.findById("wnd[0]").maximize self.session.findById("wnd[0]/tbar[0]/okcd").text = "tk11" self.session.findById("wnd[0]").sendVKey(0) self.session.findById("wnd[0]/usr/ctxtRV13A-KSCHL").text = row.FreightType elif row.FreightType == "Y154" or row.FreightType == "y154" or row.FreightType == "Y161" or row.FreightType == "y161": self.session.findById("wnd[1]/tbar[0]/btn[0]").press() self.session.findById("wnd[0]/usr/ctxtKOMG-TDLNR").text = row.Serviceagentf self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1A").text = row.CountryofDeparture self.session.findById("wnd[0]/usr/ctxtKOMG-LZONEA").text = row.DepartureZone self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1Z").text = row.DestinationCountry self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").text = row.Equipment self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").setFocus() self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").caretPosition = 4 self.session.findById("wnd[0]").sendVKey (0) self.session.findById("wnd[0]/usr/tblSAPMV13ATCTRL_FAST_ENTRY/ctxtKOMG- data['Check'] = data['ID'].shift(-1) for index_2, row_1 in data.iterrows(): CurrentRow = row_1['ID'] NextRow = row_1['Check'] if NextRow: if CurrentRow == NextRow: self.session.findById("wnd[1]/usr/ctxtX_CHAR_VAL").text = " 0,000 A" self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").text = row_1.KeyRow self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").setFocus() else: self.session.findById("wnd[0]").sendVKey (0) self.session.findById("wnd[0]/tbar[0]/btn[11]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press()
解决方案
原代码的核心问题是:内循环遍历整个DataFrame,没有正确记录停止位置,且反复修改DataFrame的Check列效率低下。以下两种方法可以实现“外层循环从内循环停止索引继续执行”的需求:
方法1:按连续ID分组处理
利用pandas的分组特性,直接把连续相同ID的行归为一组,外层循环遍历分组,自然跳过已处理的行,无需手动控制索引。
def create_freights(self): self.connect_sap() self.file = self.txt_file.text() data = pd.read_excel(self.file) data.columns = data.columns.str.replace(" ", "_") # 按连续相同的ID分组(用cumsum生成分组标识) for _, group in data.groupby((data['ID'] != data['ID'].shift()).cumsum()): first_row = group.iloc[0] freight_type = first_row.FreightType.lower() if freight_type == "y601": # Y601类型的处理逻辑 self.session.findById("wnd[0]").maximize self.session.findById("wnd[0]/tbar[0]/okcd").text = "tk11" self.session.findById("wnd[0]").sendVKey(0) self.session.findById("wnd[0]/usr/ctxtRV13A-KSCHL").text = first_row.FreightType elif freight_type in ["y154", "y161"]: # Y154/Y161类型的初始操作 self.session.findById("wnd[1]/tbar[0]/btn[0]").press() self.session.findById("wnd[0]/usr/ctxtKOMG-TDLNR").text = first_row.Serviceagentf self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1A").text = first_row.CountryofDeparture self.session.findById("wnd[0]/usr/ctxtKOMG-LZONEA").text = first_row.DepartureZone self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1Z").text = first_row.DestinationCountry self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").text = first_row.Equipment self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").setFocus() self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").caretPosition = 4 self.session.findById("wnd[0]").sendVKey(0) # 补全原代码中截断的控件操作 # 处理当前组内的所有行 for _, row_1 in group.iterrows(): self.session.findById("wnd[1]/usr/ctxtX_CHAR_VAL").text = " 0,000 A" self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").text = row_1.KeyRow self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").setFocus() # 组处理完成后的收尾操作 self.session.findById("wnd[0]").sendVKey(0) self.session.findById("wnd[0]/tbar[0]/btn[11]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press()
方法2:手动用while循环控制索引
放弃iterrows(),直接用索引变量追踪当前位置,内循环处理完连续ID的行后,更新外层索引到下一个未处理的位置。
def create_freights(self): self.connect_sap() self.file = self.txt_file.text() data = pd.read_excel(self.file) data.columns = data.columns.str.replace(" ", "_") current_idx = 0 total_rows = len(data) while current_idx < total_rows: row = data.iloc[current_idx] freight_type = row.FreightType.lower() if freight_type == "y601": # Y601类型处理 self.session.findById("wnd[0]").maximize self.session.findById("wnd[0]/tbar[0]/okcd").text = "tk11" self.session.findById("wnd[0]").sendVKey(0) self.session.findById("wnd[0]/usr/ctxtRV13A-KSCHL").text = row.FreightType current_idx += 1 # 处理完单行,索引+1 elif freight_type in ["y154", "y161"]: # Y154/Y161类型初始操作 self.session.findById("wnd[1]/tbar[0]/btn[0]").press() self.session.findById("wnd[0]/usr/ctxtKOMG-TDLNR").text = row.Serviceagentf self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1A").text = row.CountryofDeparture self.session.findById("wnd[0]/usr/ctxtKOMG-LZONEA").text = row.DepartureZone self.session.findById("wnd[0]/usr/ctxtKOMG-LAND1Z").text = row.DestinationCountry self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").text = row.Equipment self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").setFocus() self.session.findById("wnd[0]/usr/ctxtKOMG-YYRDTFRTP").caretPosition = 4 self.session.findById("wnd[0]").sendVKey(0) # 补全原代码截断的控件操作 # 找到当前ID连续的最后一行索引 current_id = row['ID'] end_idx = current_idx while end_idx < total_rows and data.iloc[end_idx]['ID'] == current_id: row_1 = data.iloc[end_idx] self.session.findById("wnd[1]/usr/ctxtX_CHAR_VAL").text = " 0,000 A" self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").text = row_1.KeyRow self.session.findById("wnd[1]/usr/ctxtY_CHAR_VAL").setFocus() end_idx += 1 # 收尾操作 self.session.findById("wnd[0]").sendVKey(0) self.session.findById("wnd[0]/tbar[0]/btn[11]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press() self.session.findById("wnd[0]/tbar[0]/btn[3]").press() # 更新外层索引到连续ID组的下一行 current_idx = end_idx
内容的提问来源于stack exchange,提问作者Gustavo Sutto
相关产品推荐
相关产品推荐

