Pandas删除DataFrame行无效?求助解决循环删除失效问题
问题根源
你的代码里df.drop(i)没生效有两个核心原因:
- Pandas的
drop()方法默认返回一个新的DataFrame,不会修改原对象,除非显式指定inplace=True参数; - 你用正序循环遍历
range(len(df)),每删除一行后,DataFrame的行索引和实际行数会错位——比如删除第0行后,原来的第1行变成了新的第0行,但循环还会继续处理i=1,直接跳过了新的第0行,导致大量该删除的行没被处理。
解决方案
推荐用Pandas的向量化操作替代循环,既高效又避免索引错位问题,同时满足你的需求:
import os import pandas as pd default_path = os.path.dirname(os.path.abspath(__file__)) start_urls = [] error_csv_path = f'{default_path}/amazon_permalink_error.csv' completed_csv_path = f'{default_path}/amazon_permalink.csv' if os.path.exists(error_csv_path): df = pd.read_csv(error_csv_path) if not df.empty: # 获取已完成的ISBN列表 all_completedISBN = pd.read_csv(completed_csv_path)['ISBN'].tolist() # 提取sku中的ISBN部分(从最后一个/分割取末尾) df['extracted_isbn'] = df['sku'].str.split('/').str[-1] # 生成布尔掩码:判断哪些行的ISBN不在已完成列表中 mask = ~df['extracted_isbn'].isin(all_completedISBN) # 生成start_urls:直接用布尔索引筛选 start_urls = df.loc[mask, 'sku'].tolist() # 保留需要的行(或者删除不需要的行,效果一致) df = df.loc[mask] # 如果处理后DF为空,删除原错误文件 if df.empty: os.remove(error_csv_path) else: # 可选:保存处理后的DF覆盖原文件(如果需要) df.drop(columns=['extracted_isbn']).to_csv(error_csv_path, index=False) else: os.remove(error_csv_path)
关键改进点
- 用
str.split('/').str[-1]批量提取ISBN,替代循环里的iloc[i]['sku'].split('/')[-1]; - 用
isin()和布尔掩码实现批量判断,避免循环遍历; - 直接通过布尔索引筛选行,避免
drop()的索引问题; - 代码更简洁,效率比循环高几个数量级(尤其是数据量大的时候)。
如果一定要用循环写法(不推荐),可以这样修正:
# 倒序遍历,避免索引错位 for i in range(len(df)-1, -1, -1): isbn = df.iloc[i]['sku'].split('/')[-1] if isbn not in all_completedISBN: start_urls.append(df.iloc[i]['sku']) else: # 加上inplace=True修改原DF df.drop(i, inplace=True)
内容的提问来源于stack exchange,提问作者viltx
相关产品推荐
相关产品推荐

