DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →
雨云;给项目一台云服务器

get_group 取到另一组数据:pandas 多键分类分组的顺序错位

pandas 3.0.5 在多键分组、Categorical、sort=False、observed=False 的组合下可能把标签与行位置错配,甚至让分面图标题对应错误样本。

gb.get_group((0, "low")) 返回的行,分类列却是 "mid";同一个 GroupBy 的 groups 和 indices 也对不上。若分组使用多个键、其中有 Categorical,并同时设置 sort=False, observed=False,要检查标签顺序与行位置错配。

pandas 3.0.5 有这条具体失败路径:数据中分类值首次出现的顺序与 categories 顺序不同,标签按一种顺序生成,行位置按另一种顺序生成,再配成字典。get_group() 依赖这些位置,所以可能静默返回别组的数据。pandas 3.1.0 的正式版本已包含对应修正。

先查行里的真实分类,不以字典键作为证明

下面的示例刻意让 mid 先出现,但 categories 中 low 在前:

import pandas as pd

df = pd.DataFrame({"x": [0, 0, 1, 1], "g": ["mid", "low", "mid", "low"]})
df["g"] = pd.Categorical(df["g"], categories=["low", "mid"], ordered=True)
gb = df.groupby(["x", "g"], sort=False, observed=False)
selected = gb.get_group((0, "low"))
assert selected["x"].eq(0).all()
assert selected["g"].eq("low").all()

分组键出现在字典中,只证明字典有这个标签。验证应检查取回的每行是否满足全部键。需要使用 indices 时,要用 iloc 按位置取行;groups 给的是索引标签。默认整数索引恰好与位置相同时,两者容易被误当成相同接口。

不能更新依赖时,用明确条件取需要的一组

已知只需一个键组合,可在确认缺失值政策后直接筛选原表:

selected = df.loc[df["x"].eq(0) & df["g"].eq("low")]

这不是完整 GroupBy 替代,只适用于这里明确的标量键组合。复杂键、缺失键和未观测类别应按原分组约定处理。不能把 observed 随意改成 True 后忽略未观测组,也不能删除重复行来让输出数量看似正确。

如果业务并不要求首次出现顺序,采用排序分组也需要重新核对输出顺序和未观测组;它属于有条件的替代,不是所有图表都可以无影响切换的选项。

分面图要核对标签与实际样本

依赖 get_group() 的绘图库也可能继承这条问题。图没有报错、每个面板都画了曲线,不等于面板标题对应正确数据。更新到包含修正的正式版本后,保留原分类顺序与行顺序,逐组比对键、样本标识、数量以及图中的实际数值。

至少覆盖首次出现顺序与分类顺序相同、不同两种输入,并保留多键组合。若已输出错误图或统计,需要从原输入重新生成;把图上的标题交换位置,只会把错误暂时藏起来。