Pandas MultiIndex插入分组求和索引层出现NaN问题求解
问题场景
需要在Pandas MultiIndex结构的Warnings、equip两个索引层之间新增索引层,存储每个Warnings层级下count per equip列的求和结果,要求最终0级索引Warnings的条目数量不变,示例中三个warning对应的预期求和值分别为103、109、123。
初始测试数据构造代码:
import pandas as pd idx = pd.MultiIndex.from_product([['warning1', 'warning2', 'warning3'], ['ff0001', 'ff0002', 'ff0003']], names=['Warnings', 'equip']) col = ['count per equip'] df = pd.DataFrame([100,2,1,44,45,20,25,98,0], idx, col)
原有错误实现运行后所有数值变为NaN,代码如下:
df = df.assign(total=df.groupby(level=[0]).size()).set_index('total', append=True).reorder_levels(['Warnings','total','equip'])
错误原因
- 聚合方法用错:
groupby(level=[0]).size()统计的是每个分组的行数,本示例中每个Warnings下固定3个equip,返回值全为3,完全不是count per equip列的求和结果 - 结果索引无法对齐:普通
groupby聚合返回的结果是按Warnings去重后的聚合值,索引只有Warnings一层,直接assign到原表时无法和原表的双层索引匹配,导致生成的total列全为NaN,后续设为索引后自然所有数据行错位显示为NaN。
正确实现代码
使用transform执行分组求和,该方法会返回和原表长度完全一致、索引逐行对齐的聚合结果,再追加为索引层调整顺序即可:
# 逐行匹配对应Warnings分组的求和值 df['total'] = df.groupby(level='Warnings')['count per equip'].transform('sum') # 将total追加为索引层,调整索引顺序到Warnings和equip之间 df = df.set_index('total', append=True).reorder_levels(['Warnings', 'total', 'equip'])
运行后输出结果完全符合预期:
count per equip Warnings total equip warning1 103 ff0001 100 ff0002 2 ff0003 1 warning2 109 ff0001 44 ff0002 45 ff0003 20 warning3 123 ff0001 25 ff0002 98 ff0003 0
内容的提问来源于stack exchange,提问作者Pedro de Sá
相关产品推荐
相关产品推荐

