如何获取Polars分类列所有可能值的物理表示?
Polars分类列:获取全量潜在分类的物理编码与无间隔编码设置
一、获取所有潜在分类的物理表示
Polars中分类列的物理编码是按分类定义的顺序从0开始的连续整数,即使某些分类在数据中没有实际出现,编码也会保留对应的位置。要获取所有潜在分类的物理编码,有两种简洁方法:
方法1:基于分类数量生成序列
先获取分类总数,直接生成对应范围的整数序列:
# 获取分类列的总分类数 total_cats = res.select(pl.col.bucket.cat.get_categories()).shape[0] # 生成对应物理编码的DataFrame pl.DataFrame({"bucket": range(total_cats)}, schema={"bucket": pl.UInt32})
输出结果:
shape: (3, 1) ┌────────┐ │ bucket │ │ --- │ │ u32 │ ╞════════╡ │ 0 │ │ 1 │ │ 2 │ └────────┘
方法2:通过临时分类Series映射
提取所有分类的字符串列表,转换为分类类型Series后直接获取物理编码:
# 获取所有分类的字符串列表 all_cats = res.select(pl.col.bucket.cat.get_categories()).to_series().to_list() # 转换为分类Series并提取物理编码,转为DataFrame pl.Series(all_cats, dtype=pl.Categorical).to_physical().to_frame()
该方法同样能得到与需求一致的输出。
二、设置无间隔的物理编码
你遇到的编码间隔问题,是因为cut生成的分类包含了数据中未出现的区间(比如例子中的(1,3]),Polars会保留所有定义的分类,因此物理编码不会跳过未出现的分类位置。
如果需要让物理编码仅对应数据中实际存在的分类,且为连续无间隔的整数,可通过重新设置分类实现:
# 提取数据中实际出现的分类 existing_cats = res.select(pl.col.bucket.unique()).to_series().to_list() # 重新设置分类列的可选值,此时物理编码会按现有分类顺序从0开始连续分配 res_continuous = res.with_columns( pl.col.bucket.cat.set_categories(existing_cats) )
验证物理编码:
res_continuous.select(pl.col.bucket.to_physical())
输出结果:
shape: (7, 1) ┌────────┐ │ bucket │ │ --- │ │ u32 │ ╞════════╡ │ 0 │ │ 0 │ │ 0 │ │ 1 │ │ 1 │ │ 1 │ │ 1 │ └────────┘
此时物理编码仅包含实际出现的分类对应的连续整数,无间隔。
内容的提问来源于stack exchange,提问作者roman
相关产品推荐
相关产品推荐

