pandas中for循环删除DataFrame指定行失效的解决方法
问题根源
你的代码没生效是因为存在3个核心错误:
- 循环写法逻辑错误:
for df['year'].values in anos会把列表anos里的年份挨个赋值给df['year']列,直接篡改原始数据的年份字段,完全没有实现「判断行年份是否在目标列表中」的逻辑。 drop方法用法错误:当inplace=True时,drop会直接修改原DataFrame、返回值为None,你再把None赋值给df,会直接把df变量置空。- 筛选条件不全:循环内的删除判断没有加年份限制,就算循环能正常跑,也会把2016、2020这两个闰年的合法2月29日数据一起删掉,不符合你的需求。
另外pandas做行筛选根本不需要写for循环,向量化判断可以一次性完成所有匹配,性能远高于循环写法。
修正代码
直接通过布尔掩码一次性筛除所有无效行即可,代码简洁且不会出错:
anos = [2013,2014,2015,2017,2018,2019,2021,2022] # 构造无效行的匹配条件:2月29日+年份在非闰年列表内 invalid_rows = (df["month"] == 2) & (df["day"] == 29) & (df["year"].isin(anos)) # 保留所有非无效行,可选重置索引 df = df[~invalid_rows].reset_index(drop=True)
如果你更习惯用drop方法删除对应索引,注意不要混用inplace=True和变量赋值:
anos = [2013,2014,2015,2017,2018,2019,2021,2022] # 先拿到所有无效行的索引 invalid_index = df[(df["month"] == 2) & (df["day"] == 29) & (df["year"].isin(anos))].index # 原地删除,不需要重新赋值 df.drop(invalid_index, inplace=True) df.reset_index(drop=True, inplace=True)
补充说明:你要删除的这些2月29日刚好都属于非闰年,本质是源数据生成时的日期对齐错误,用上面的条件可以100%匹配到你要删的脏数据,不会误删闰年的合法2月29日记录。
内容的提问来源于stack exchange,提问作者Vinícius Franca
相关产品推荐
相关产品推荐

