Pandas多索引DataFrame按年龄区间行求和的高效实现方法
1965 0 34 45
1965 1 41 34
...
1965 50 56 22
1966 0 10 34
...
我希望对A列(以及B列)求某年龄区间(如10至20)内所有行的和。我尝试过使用`.xs()`方法,例如: ```python pops.xs(20, level='age')
这个方法能获取各年份下年龄为20的行,但没办法实现多年龄筛选并按年份求和。比如针对年龄0和1,我想要得到这样的结果:
A B year 1895 23 26 ... 1965 75 79 ...
请问有没有优雅且高效的实现方法?
解决方案
这里有几种优雅又高效的方法可以实现你的需求,根据你的DataFrame规模和个人偏好挑选就行:
方法一:布尔索引 + groupby
这是最直观的方式——先筛选出年龄在目标区间内的行,再按year分组求和:
# 筛选年龄0-1的行,按year聚合求和 result = pops[(pops.index.get_level_values('age') >= 0) & (pops.index.get_level_values('age') <= 1)].groupby(level='year').sum()
如果是连续的年龄区间(比如10到20),可以用between()简化条件:
age_mask = pops.index.get_level_values('age').between(10, 20) result = pops[age_mask].groupby(level='year').sum()
方法二:使用.query()方法
如果你偏爱更简洁易读的语法,.query()会很适合,写条件就像写自然语言一样:
# 筛选年龄在0到1之间,按year求和 result = pops.query('age >= 0 and age <= 1').groupby(level='year').sum() # 连续区间也可以用between语法 result = pops.query('age between 10 and 20').groupby(level='year').sum()
方法三:.loc切片(适合有序多索引)
如果你的多索引是按year和age有序排列的,.loc切片的效率会非常高,尤其处理大型DataFrame时:
# 匹配所有年份,年龄从0到1的行,再按year求和 result = pops.loc[(slice(None), slice(0, 1)), :].groupby(level='year').sum()
这里slice(None)代表匹配所有year值,slice(0,1)则指定了年龄的范围。
方法四:groupby结合自定义函数(复杂需求适用)
如果需要同时计算多个年龄区间的和,或者分组后要做更灵活的计算,可以用自定义函数配合apply():
def sum_age_range(group, min_age, max_age): age_filter = group.index.get_level_values('age').between(min_age, max_age) return group[age_filter][['A', 'B']].sum() # 计算每个年份下年龄0-1的A、B列和 result = pops.groupby(level='year').apply(sum_age_range, min_age=0, max_age=1)
性能小贴士
- 若你的DataFrame规模很大,优先选方法一的
between版本或方法三的.loc切片,它们都是向量化操作,比循环式的apply()快很多。 - 提前用
pops = pops.sort_index()把多索引排好序,能进一步提升groupby和切片的效率。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

