Polars LazyFrame collect时signal列dtype从Int8变Int32问题求助
Polars LazyFrame 列类型不一致问题:Schema显示Int8但collect后变为Int32
我有一个包含多列的pl.LazyFrame,其中一列名为signal,预期数据类型为pl.Int8,仅包含0和1。调用collect_schema()验证时,该列的dtype符合预期;但执行collect()转换为DataFrame后,该列的dtype变为pl.Int32。无法复现极简示例,附上实际LazyFrame的行为表现:
In [1]: lf.select(pl.col("signal")).collect_schema() Out[1]: Schema([('signal', Int8)]) In [2]: lf.select(pl.col("signal")).collect() Out[2]: shape: (7_556, 1) ┌────────┐ │ signal │ │ --- │ │ i32 │ ╞════════╡ │ 0 │ │ 0 │ │ 0 │ │ 0 │ │ 1 │ │ … │ │ 1 │ │ 1 │ │ 1 │ │ 0 │ │ 0 │ └────────┘ In [3]: lf.select(pl.col("signal")).collect().collect_schema() Out[3]: Schema([('signal', Int32)]) In [4]: lf.select(pl.col("signal")).collect().describe() Out[4]: shape: (9, 2) ┌────────────┬──────────┐ │ statistic ┆ signal │ │ --- ┆ --- │ │ str ┆ f64 │ ╞════════════╪══════════╡ │ count ┆ 7556.0 │ │ null_count ┆ 0.0 │ │ mean ┆ 0.55585 │ │ std ┆ 0.496904 │ │ min ┆ 0.0 │ │ 25% ┆ 0.0 │ │ 50% ┆ 1.0 │ │ 75% ┆ 1.0 │ │ max ┆ 1.0 │ └────────────┴──────────┘
排查解决方向
- 检查LazyFrame构建流程:
- 确认
signal列的数据源:如果是从外部文件读取,检查读取参数是否存在类型推断偏差,比如CSV读取时未指定dtypes参数导致隐式转换。 - 排查中间操作:是否对
signal列执行过跨类型运算、聚合、自定义函数等操作,这类操作可能触发Polars自动提升类型,但collect_schema()未同步反映最终执行结果。
- 确认
- 查看执行计划:
- 调用
lf.select(pl.col("signal")).explain(),通过执行计划定位是否有步骤导致类型被提升,执行计划会清晰展示每一步的类型变化逻辑。
- 调用
- 强制类型转换验证:
- 在collect前显式转换类型:
lf.select(pl.col("signal").cast(pl.Int8)).collect(),如果转换后能保持Int8类型,说明原执行计划存在隐式类型提升;如果仍变为Int32,可能是Polars内部类型处理问题。
- 在collect前显式转换类型:
- 升级Polars版本:
- 不同版本的Polars可能存在类型推断或执行计划的Bug,尝试升级到最新稳定版,确认问题是否消失。
是否属于Bug?
如果排查后确认无任何显式/隐式类型提升操作,且最新版本仍存在该问题,大概率是Polars的Bug。此时可收集执行计划、Polars版本、LazyFrame关键构建步骤,提交到Polars官方仓库反馈。
内容的提问来源于stack exchange,提问作者Andi
相关产品推荐
相关产品推荐

