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

如何在Python Polars中创建FICO分数降序十分位列?

原代码问题出在哪?
  • 排序方向反了:rank()默认是升序计算,高FICO分(比如850)的rank值会比低分大,你再除以总行数乘10,结果肯定小于1,转成UInt32直接变成0。
  • 分组逻辑不对:直接用rank/总行数*10的方式不适合做十分位分组,尤其是当总行数不是10的倍数时,分组会乱。
  • 缺失值没处理:如果fico列有null,rank()会返回null,最终fico_decile也会是null。
两种可行的解决方法

方法1:修正rank逻辑

先按降序排名,再计算十分位,顺便处理缺失值:

df1 = df.with_columns(
    pl.when(pl.col('fico').is_not_null())
      .then(pl.col('fico').rank(method='dense', descending=True).apply(lambda x: (x - 1) // (df.height / 10) + 1).cast(pl.UInt32))
      .otherwise(None)
      .alias('fico_decile')
)

嫌lambda麻烦的话,换个更简洁的写法:

df1 = df.with_columns(
    pl.when(pl.col('fico').is_not_null())
      .then((pl.col('fico').rank(method='dense', descending=True) / (df.height / 10)).ceil().cast(pl.UInt32))
      .otherwise(None)
      .alias('fico_decile')
)
  • descending=True:让高分的rank值最小(850的rank是1)
  • ceil():向上取整,保证每个rank都落到正确的十分位组里

方法2:用qcut直接分(更简单)

Polars自带的qcut()可以直接按等频分位分组,一步到位:

df1 = df.with_columns(
    pl.col('fico')
      .qcut(10, labels=[str(i) for i in range(1, 11)], descending=True)
      .alias('fico_decile')
      .cast(pl.UInt32)
)
  • qcut(10):把数据分成10个等数量的组
  • descending=True:最高分组对应标签1,最低对应10
  • 要是有缺失值,加个.fill_null(None)就行
额外提醒

如果不是要等频分组,而是按固定分数区间(比如800-850算1,750-799算2),直接用when-then写区间判断就行。另外如果后续会过滤数据,别用df.height,换成pl.count().over(),这样行数会自动对应当前数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:13:21