如何用更优雅的Pandas方法筛选含指定年份全集的DataFrame?
需求说明
我有如下CSV数据集:
country,year,happiness A,2008,3.72 A,2009,4.4 A,2011,3.83 B,2009,5.49 B,2010,5.27 B,2011,5.87 B,2012,5.51 C,2010,5.46 C,2011,5.32 D,2009,6.42 D,2010,6.44 D,2011,6.78
目标是筛选出仅包含2009、2010和2011这三年数据的国家,同时仅保留这三年的记录。期望结果如下:
country,year,happiness B,2009,5.49 B,2010,5.27 B,2011,5.87 D,2009,6.42 D,2010,6.44 D,2011,6.78
可见,国家A和C因未覆盖全部三年被排除,国家B的2012年记录也被排除。
我已通过以下Pandas代码实现需求:
y09 = df.loc[df['year'] == 2009, 'country'] y10 = df.loc[df['year'] == 2010, 'country'] y11 = df.loc[df['year'] == 2011, 'country'] countries = set(y09) & set(y10) & set(y11) years = [2009, 2010, 2011] filtered = df.loc[df['country'].isin(countries) & df['year'].isin(years), :]
但希望找到一种更优雅的Pandas实现方式,使其能够轻松扩展到更大的年份范围(例如50年)。
优化方案
提供两种高扩展性的实现方式,只需修改目标年份集合即可适配任意范围:
方法一:分组+集合子集校验
# 定义目标年份集合 target_years = {2009, 2010, 2011} # 按国家分组,校验该国家的年份集合是否包含所有目标年份 valid_countries = df.groupby('country')['year'].apply( lambda x: target_years.issubset(set(x)) ).loc[lambda res: res].index # 筛选符合条件的国家及目标年份数据 filtered = df[(df['country'].isin(valid_countries)) & (df['year'].isin(target_years))]
方法二:分组计数匹配
# 定义目标年份列表 target_years = [2009, 2010, 2011] required_year_count = len(target_years) # 先筛选目标年份数据,再按国家统计不同年份的数量 country_year_stats = df[df['year'].isin(target_years)].groupby('country')['year'].nunique() # 筛选出年份数量等于目标年份总数的国家 valid_countries = country_year_stats[country_year_stats == required_year_count].index # 最终筛选数据 filtered = df[(df['country'].isin(valid_countries)) & (df['year'].isin(target_years))]
这两种方法无需逐个年份编写提取逻辑,修改target_years即可快速适配更大的年份范围。
内容的提问来源于stack exchange,提问作者Kevin Markham
相关产品推荐
相关产品推荐

