使用pl.scan_parquet时如何强制分区列转为兼容超类型?
解决Parquet分区列类型精度不一致的加载问题
针对不同分区列类型(如float32/float64)不兼容导致的SchemaError,有以下几种实现类似pl.concat(..., how="vertical_relaxed")自动转换兼容超类型的方法:
方法1:逐个扫描分区后用vertical_relaxed合并
这是最贴合需求的直接方式,手动遍历所有分区文件,分别扫描后合并:
import polars as pl from glob import glob # 匹配所有分区的Parquet文件 partition_files = glob("path/to/your/parquet/partitions/**/*.parquet", recursive=True) # 逐个扫描每个分区 scanned_partitions = [pl.scan_parquet(file) for file in partition_files] # 用vertical_relaxed合并,自动提升到兼容超类型 combined_df = pl.concat(scanned_partitions, how="vertical_relaxed").collect()
这种方式完全复刻vertical_relaxed的行为,会自动将列转换为能容纳所有分区数据的最小兼容类型(比如float32和float64合并为float64)。
方法2:通过PyArrow统一Schema后读取
如果想在读取阶段就统一类型,可借助PyArrow定义统一Schema,指定有问题的列为高精度类型:
import polars as pl import pyarrow as pa import pyarrow.parquet as pq # 定义统一Schema,将目标列设为高精度类型(替换成你的列名和对应类型) custom_schema = pa.schema([ ("col1", pa.int64()), ("XXX", pa.float64()), # 强制该列用float64 ("col3", pa.string()) ]) # 用PyArrow读取整个数据集,应用自定义Schema pq_dataset = pq.ParquetDataset("path/to/your/parquet/partitions", schema=custom_schema) arrow_table = pq_dataset.read() # 转换为Polars DataFrame combined_df = pl.from_arrow(arrow_table)
这种方式提前强制列类型,避免扫描时的Schema冲突,适合明确知道哪些列存在类型差异的场景。
方法3:Polars扫描时指定schema_overrides
Polars的scan_parquet支持schema_overrides参数,可直接覆盖指定列的类型,实现统一:
import polars as pl # 指定目标列强制为兼容的超类型 combined_df = pl.scan_parquet( "path/to/your/parquet/partitions/**/*.parquet", schema_overrides={"XXX": pl.Float64} ).collect()
这个方法更简洁,无需手动遍历分区,直接在扫描阶段统一列类型,本质是提前将所有分区的目标列强制转换为指定类型,避免Schema冲突。
内容的提问来源于stack exchange,提问作者ini
相关产品推荐
相关产品推荐

