Python中DataFrame循环无法迭代问题求助:循环仅执行第一行即停止
问题诊断与修复方案
从你的代码和输出来看,循环停在第一行的问题主要来自几个逻辑和索引使用的错误,我来一步步帮你拆解并修复:
核心问题分析
索引使用错误:你用
d.loc[i]取行,但loc是按标签索引而非位置索引。如果你的DataFramed的行标签不是从1开始的连续整数,或者d只有一行标签为1的行,那么即使i递增,也会一直取到同一行(甚至报错)。循环终止逻辑失效:你设置了
done变量,但没有用它来终止外层循环——done只是被赋值,没有任何代码检查它并跳出循环,导致循环逻辑混乱。action==0的嵌套循环冗余:每次外层循环都会遍历整个
df,最后reward会被覆盖为最后一次匹配的结果,而且如果h['id']存在多个匹配,会重复打印"Equals",这大概率不是你想要的逻辑。
修正后的代码示例
# 初始化终止标记 done = False # 控制最多处理100行,同时结合total_count判断 while not done and self.total_count < 100: # 直接用iterrows遍历d的每一行,避免索引问题 for idx, h in d.iterrows(): if self.total_count >= 100: done = True break self.total_count += 1 print(h) if action == 0: # 用向量化操作替代嵌套循环,高效判断是否存在匹配id if df['id'].eq(h['id']).any(): reward = 1 print("Equals") else: reward = 0 self.miss_count += 1 elif action == 1: # 避免df只有一行时删除出错 if len(df) > 1: num = random.randrange(len(df)) df = df.drop(df.index[num]) # 追加行到df df = df.append(h, ignore_index=True) reward = 0 print(df) # 如果d的行已经处理完,也终止循环 done = True info = {} return df, reward, done, info
关键修改说明
- 正确遍历行:用
d.iterrows()直接遍历d的每一行,彻底避免手动处理索引的坑。 - 有效控制循环终止:用
while循环结合done标记,确保self.total_count达到100时立刻停止循环。 - 优化匹配逻辑:用
df['id'].eq(h['id']).any()替代嵌套循环,既高效又简洁,不用遍历整个DataFrame就能判断是否存在匹配id。 - 增加边界判断:在action==1的逻辑里加了
len(df) >1的判断,防止df只有一行时执行删除操作报错。
如果你原本是想固定执行100次循环(不管d有多少行),可以改成下面的写法,循环取d的行:
done = False for _ in range(100): if self.total_count >= 100: done = True break self.total_count += 1 # 循环取d的行,即使d行数不足也能重复获取 h = d.iloc[self.total_count % len(d)] print(h) # 后续action逻辑同上...
内容的提问来源于stack exchange,提问作者Lala
相关产品推荐
相关产品推荐

