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

如何在Polars中创建带百分比的交叉表?解决代码生成器类型错误

解决Polars交叉表百分比转换的TypeError问题
  • 错误原因:crosstab.select()无法直接处理生成器对象,当同时传入索引列表达式和生成器时,Polars会抛出类型错误。单独调用时能运行是因为Polars对单个可迭代参数做了兼容,但多参数场景不支持。

  • 快速修复:将生成器转换为列表,修改调用代码:

crosstab.select(cs.by_index(0), *list(perc_cols(crosstab)))

或者先把表达式整理成列表再传入:

exprs = [cs.by_index(0)] + list(perc_cols(crosstab))
crosstab.select(exprs)
  • 优化实现(更贴合Polars原生风格,避免转numpy):
    原函数依赖numpy计算总和,改用Polars原生的水平求和方法,更高效且无需类型转换:
def perc_cols(df):
    # 计算每行的总和(排除第一列索引)
    row_total = pl.sum_horizontal(df.columns[1:])
    for col in df.columns[1:]:
        # 可选保留两位小数提升可读性
        yield (pl.col(col) / row_total * 100).round(2)
  • 完整可运行示例:
import polars as pl
import polars.selectors as cs

df = pl.DataFrame({"a": [2, 0, 1, 0, 0, 0], "b": [1, 1, 1, 0, 0, 1]})

crosstab = (
    df.pivot(on="b", index="a", values="b", aggregate_function="len", sort_columns=True)
    .fill_null(0)
    .sort("a")
)

def perc_cols(df):
    row_total = pl.sum_horizontal(df.columns[1:])
    for col in df.columns[1:]:
        yield (pl.col(col) / row_total * 100).round(2)

result = crosstab.select(cs.by_index(0), *list(perc_cols(crosstab)))
print(result)

运行输出:

shape: (3, 3)
┌─────┬──────────┬──────────┐
│ a   ┆ 0        ┆ 1        │
│ --- ┆ ---      ┆ ---      │
│ i64 ┆ f64      ┆ f64      │
╞═════╪══════════╪══════════╡
│ 0   ┆ 33.33    ┆ 66.67    │
│ 1   ┆ 0.0      ┆ 100.0    │
│ 2   ┆ 0.0      ┆ 100.0    │
└─────┴──────────┴──────────┘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 08:52:35