You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中Categorical列转整数出现异常映射?原因与解决办法

Polars Categorical列转数值类型映射异常问题解决

问题背景

你在Polars中通过qcut生成了名为decile的Categorical列,标签为q10、q09...q01(对应逻辑上的10到1分位数)。但直接用pl.col('decile').cast(pl.Int8)转换时,结果变成了0-9的整数,和标签里的数值(10-1)完全不符——这是因为Categorical转数值时,取的是类别在内部的索引(从0开始),而非标签文本里的数字。

你的最小可复现代码:

import numpy as np
import polars as pl

size = 1e3
df = pl.DataFrame({
    "id": np.random.randint(50, size=int(size), dtype=np.uint16),
    "amount": np.round(np.random.uniform(10, 100000, int(size)).astype(np.float32), 2),
    "quantity": np.random.randint(1, 7, size=int(size), dtype=np.uint16),
})
df = (df
      .group_by("id")
      .agg(revenue=pl.sum("amount"), tot_quantity=pl.sum("quantity"))
     )
df = (df.with_columns(
    pl.col('revenue')
    .qcut(10, labels=[f'q{i:02}' for i in range(10, 0, -1)])
    .alias("decile")
))

解决方案

方法1:先转字符串再提取数字转换

直接将Categorical转为字符串,提取标签中的数字部分后再转整数:

df = df.with_columns(
    # 提取标签中的数字,转Int8
    pl.col('decile').cast(pl.String).str.extract(r'(\d+)').cast(pl.Int8).alias('decile_num')
)

方法2:通过类别映射转换

先获取Categorical的所有类别标签,创建标签到目标数值的映射字典,再批量替换:

# 获取所有类别标签
cat_labels = df['decile'].cat.get_categories()
# 构建映射:qxx → xx对应的整数
label_map = {label: int(label.lstrip('q')) for label in cat_labels}

df = df.with_columns(
    pl.col('decile').map_dict(label_map).alias('decile_num')
)

方法3:在qcut阶段直接生成数值标签

如果不需要保留字符串格式的分位数标签,可以直接在qcut时指定数值型标签,一步到位:

df = df.with_columns(
    pl.col('revenue')
    .qcut(10, labels=list(range(10, 0, -1)))  # 直接用10到1的整数作为标签
    .alias("decile")
)

如果需要同时保留字符串和数值标签,可以生成两列:

df = df.with_columns(
    decile_str=pl.col('revenue').qcut(10, labels=[f'q{i:02}' for i in range(10, 0, -1)]),
    decile_num=pl.col('revenue').qcut(10, labels=list(range(10, 0, -1)))
)

关键原因说明

Polars的Categorical类型本质是用整数索引映射类别标签,当直接cast为数值类型时,返回的是类别在内部的索引值(从0开始),而非标签文本中的数字。你的decile列类别顺序是['q10', 'q09', ..., 'q01'],所以索引0对应q10,索引9对应q01,直接转换就会得到0-9的结果,和预期不符。


内容的提问来源于stack exchange,提问作者Omar AlSuwaidi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:11:28