如何按CODE和YEAR_MONTH分组判断PP列是否全为NaN?
问题解决:Pandas分组判断列是否全为NaN
原始数据
现有Pandas DataFrame如下:
DATE CODE PP YEAR_MONTH 9862 1991-01-01 100007 NaN 1991-01 9863 1991-01-02 100007 NaN 1991-01 9864 1991-01-03 100007 NaN 1991-01 9865 1991-01-04 100007 NaN 1991-01 9866 1991-01-05 100007 NaN 1991-01 ... ... ... ... 10541963 2020-12-27 155217 5.7 2020-12 10541964 2020-12-28 155217 0.0 2020-12 10541965 2020-12-29 155217 0.0 2020-12 10541966 2020-12-30 155217 0.0 2020-12 10541967 2020-12-31 155217 5.7 2020-12 [5347504 rows x 4 columns]
需求说明
按CODE和YEAR_MONTH分组,判断每组的PP列是否全为NaN:
- 全为NaN则返回
True - 否则返回
False
期望得到如下结果:
CODE NAN_MONTH YEAR_MONTH 100007 True 1991-01 100007 False 1991-02 100007 False 1991-03 100007 False 1991-04 100007 False 1991-05 ... ... ... 155217 True 2020-09 155217 False 2020-10 155217 False 2020-11 155217 False 2020-12
错误原因分析
你尝试的代码出现AttributeError: 'NoneType' object has no attribute 'append',是因为**list.append()是原地修改列表,不会返回新的列表对象**。当你执行yearmonths=yearmonths.append(yearmonth)时,yearmonths会被赋值为append方法的返回值None,第二次循环调用append就会报错。
解决方案
方法1:修复循环代码
去掉赋值操作,直接调用append方法:
import pandas as pd yearmonths = [] nanmonths = [] # 注意groupby的返回值是(分组键元组, 分组数据) for (code, year_month), data in df.groupby(['CODE', 'YEAR_MONTH']): checknan = data['PP'].isna().all() yearmonths.append((code, year_month)) nanmonths.append(checknan) # 将结果转换为目标DataFrame result = pd.DataFrame(yearmonths, columns=['CODE', 'YEAR_MONTH']) result['NAN_MONTH'] = nanmonths
方法2:Pandas原生分组聚合(推荐)
手动循环处理500多万行数据效率极低,推荐使用Pandas内置的分组聚合方法,性能更优:
# 方法2.1 使用apply result = df.groupby(['CODE', 'YEAR_MONTH'])['PP'].apply(lambda x: x.isna().all()).reset_index(name='NAN_MONTH') # 方法2.2 使用agg(更清晰) result = df.groupby(['CODE', 'YEAR_MONTH']).agg( NAN_MONTH=('PP', lambda x: x.isna().all()) ).reset_index()
这两种方法都会直接生成符合要求的结果DataFrame,无需手动维护列表。
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

