使用get()方法访问pd.Series多级索引无法找到对应元素
问题原因分析
这个问题我之前也踩过坑,核心是Pandas的get()方法和直接索引的行为差异导致的:
你的grouped Series的索引其实是混合类型的Object索引:
- 原两级分组生成的键是以元组形式存在的(比如
("stallion", "london")) - 后续追加的单级分组和全局均值的键是字符串(比如
"stallion"、"all_breeds")
而grouped.get()方法是严格匹配索引键的类型和值的——你传入的是列表["stallion", "london"],但索引里对应的键是元组("stallion", "london"),两者类型不匹配,所以get()找不到对应元素,只能返回默认值(None或你指定的-1)。
反观直接用grouped["stallion", "london"]的情况,Pandas的索引语法做了“语法糖”处理:当你给多级索引传入多个参数或列表时,它会自动转换成元组去匹配索引键,所以能成功找到对应值。
解决方案
方案1:快速修复——把列表改成元组
只需要将get()里的列表参数换成元组,就能严格匹配索引中的键:
print(grouped.get(("stallion", "london"))) # 现在会返回982.0 print(grouped.get(("stallion", "london"), -1)) # 返回982.0 print(f'The same? {grouped["stallion", "london"] == grouped.get(("stallion", "london")) == grouped.get(("stallion", "london"), -1)}') # 输出:The same? True
方案2:优化索引结构(更推荐)
当前混合类型的索引容易引发其他潜在问题,建议把所有索引统一为MultiIndex,让层级更清晰:
修改你追加均值的代码:
import pandas as pd a = pd.DataFrame({ "breed": ["stallion", "stallion", "stallion", "stallion", "pony", "pony", "pony"], "stable": ["hogwarts", "hogwarts", "london", None, "hogwarts", "london", "london"], "weight": [800, 900, 982, 400, 230, 300, 500] }) # 原两级分组 grouped = a.groupby(["breed", "stable"], dropna=False)["weight"].mean() # 追加breed层级的均值,将stable层级设为None,统一为MultiIndex breed_mean = a.groupby("breed", dropna=False)["weight"].mean() breed_mean.index = pd.MultiIndex.from_tuples((b, None) for b in breed_mean.index) grouped = grouped.append(breed_mean) # 追加全局均值,breed设为"all_breeds",stable设为None global_mean = pd.Series(a["weight"].mean(), index=pd.MultiIndex.from_tuples([("all_breeds", None)])) grouped = grouped.append(global_mean) # 现在测试你的降级逻辑 result = grouped.get(("stallion", "london"), grouped.get(("stallion", None), grouped.get(("all_breeds", None)))) print(result) # 输出982.0 # 如果("stallion", "london")不存在,会自动降级到("stallion", None)的均值,再不存在就用全局均值
这样修改后,整个索引的层级完全统一,不管是直接索引还是get()方法都能稳定工作,后续维护也更方便。
内容的提问来源于stack exchange,提问作者Hans Bambel
相关产品推荐
相关产品推荐

