Pandas根据列值删除行异常:执行后返回空DataFrame求解决
问题
爬取体育网站数据时创建了一个包含数百行的Pandas DataFrame,想要根据某列的值删除行(仅保留位置为WR或TE的球员,移除其他位置的球员)。编写的代码执行后返回空DataFrame,代码如下:
import pandas as pd def rec_career(): url = 'https://www.pro-football-reference.com/years/2022/receiving.htm' base_url = 'https://www.pro-football-reference.com' #Establish Dictionary player_links = dict() # Use Pandas to read table table = pd.read_html(url, attrs={'id': 'receiving'})[0] table.head() table.index = range(len(table)) for i, row in table.iterrows(): if row[4] != 'WR' or 'TE': table = table.drop(index=i) print(table) rec_career()
问题原因
- 逻辑判断错误:
if row[4] != 'WR' or 'TE'的写法不符合Python语法逻辑。这里'TE'是一个非空字符串,布尔值为True,所以整个条件永远为True,导致所有行都被删除,最终返回空DataFrame。正确的逻辑应该是判断当前值不在['WR', 'TE']列表中,或者同时不等于两个值。 - 循环修改DataFrame的风险:在
iterrows()循环中直接删除行,会导致DataFrame的索引和长度动态变化,后续循环的索引会和原数据行不匹配,容易出现遗漏或错误删除的情况,而且这种方式效率极低,不适合处理大数据集。
正确实现方法
推荐使用Pandas的向量化布尔索引(高效且简洁),避免循环操作:
import pandas as pd def rec_career(): url = 'https://www.pro-football-reference.com/years/2022/receiving.htm' # 读取网站表格 table = pd.read_html(url, attrs={'id': 'receiving'})[0] # 先清理表格中重复的表头行(网站表格第二行是重复表头) table = table[table['Pos'] != 'Pos'] # 保留位置为WR或TE的行,用列名'Pos'更直观,避免依赖列索引 table = table[table['Pos'].isin(['WR', 'TE'])] print(table) rec_career()
补充说明
- 用
isin(['WR', 'TE'])直接筛选符合条件的行,是Pandas官方推荐的向量化操作,比循环快几十倍,尤其适合处理大数据集。 - 如果不确定列名,也可以用列索引定位:
table = table[table.iloc[:, 4].isin(['WR', 'TE'])],但用列名更清晰,避免表格结构变化导致索引失效。
内容的提问来源于stack exchange,提问作者Chup91
相关产品推荐
相关产品推荐

