Pandas按CODE分组取PP列首个非空值对应YEAR报错如何解决
错误原因
- 核心问题是你混淆了全局行标签和分组后子DataFrame的位置索引:
Series.first_valid_index()返回的是该Series在原始全量DataFrame中的行标签(index值),而iloc是按子DataFrame内部的相对位置从0开始计数的。 - 比如你示例里CODE为000659的分组,第一个有效PP的行标签是3,刚好和它在子DataFrame里的位置索引一致,所以单独测试这个分组不会报错;但后续CODE(比如000543)的分组行标签是6052770起步,你把这个6位数的全局标签传给只有几千、几万行的子DataFrame的
iloc,自然会触发索引越界错误。 - 额外潜在问题:如果某个CODE分组的PP列全为NaN,
first_valid_index()会返回None,调用astype(int)也会抛出异常。
解决方法
方法1:修改原有循环逻辑
把iloc换成loc即可,loc是按行标签取值,刚好匹配first_valid_index()的返回值,同时补充全NaN分组的判断:
import pandas as pd dic={} for code, data in df.groupby('CODE'): valid_idx = data['PP'].first_valid_index() # 处理PP全为NaN的分组,可根据需求调整默认值 if valid_idx is not None: starting_year = data['YEAR'].loc[valid_idx] else: starting_year = pd.NA dic[code] = starting_year starting_years=pd.DataFrame(dic.items(), columns=['CODE', 'STARTING YEAR'])
方法2:更高效的向量化写法(推荐)
直接用groupby.apply实现,避免显式循环,处理600万行数据性能更好:
import pandas as pd starting_years = df.groupby('CODE').apply( lambda x: x['YEAR'].loc[x['PP'].first_valid_index()] if x['PP'].first_valid_index() is not None else pd.NA ).reset_index(name='START YEAR')
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

