Pandas按CODE分组后若组内PPTOT存在至少1个NaN则将组内所有PPTOT设为NaN
问题原因
- 第一,
data.dropna(subset=['PPTOT'], how='any')默认返回删除空值后的新DataFrame,你没有赋值给变量,原分组数据data没有被修改,这行代码等于没有执行。 - 第二,你的逻辑方向错误:你需要的是「分组存在NaN就将该分组所有PPTOT替换为NaN」,但
dropna是删除存在空值的行,和需求完全不符,自然得不到预期结果。 - 额外问题:
DataFrame.append方法早在pandas 1.4版本就已经被弃用,性能低下且存在潜在的类型兼容问题,不推荐使用。
正确实现方案
方案1:向量化实现(推荐,性能远高于循环)
直接用groupby.transform批量判断分组是否存在空值,再批量赋值,不需要遍历分组:
import pandas as pd import numpy as np # 逻辑:如果对应CODE分组存在PPTOT空值,就将该分组所有PPTOT设为NaN df['PPTOT'] = df['PPTOT'].where( ~df.groupby('CODE')['PPTOT'].transform(lambda x: x.isna().any()), np.nan )
方案2:修正后的循环实现(对应你原来的写法调整)
如果需要用遍历分组的写法,调整逻辑如下:
notnan_list = [] for code, data in df.groupby('CODE'): # 判断当前分组是否存在PPTOT空值 if data['PPTOT'].isna().any(): # 存在空值则将该分组所有PPTOT替换为NaN data['PPTOT'] = np.nan notnan_list.append(data) # 合并所有分组结果 notnan = pd.concat(notnan_list, ignore_index=True)
两种方案都可以得到你需要的预期结果。
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

