如何在Polars中强制以字符类型扫描CSV并导出为Parquet文件
如何在Polars中强制以字符类型扫描CSV并导出为Parquet文件
针对你的问题,核心解决方案是手动指定Polars扫描CSV时的Schema,将所有列的类型强制设置为字符串(pl.Utf8),这样可以完全绕过自动类型推断的问题,确保所有列都被解析为字符类型,同时避免类型不一致导致的报错。
修改后的完整代码
import os import polars as pl dir_list = os.listdir() for filename in dir_list: if ".txt" in filename: # 1. 获取文件列名(仅读取表头,不加载任何数据,适配超大文件) column_names = pl.scan_csv( filename, separator="|", n_rows=0 # 只读取表头行,不加载数据 ).collect().columns # 2. 构建强制Schema:所有列统一设置为字符串类型 forced_schema = {col: pl.Utf8 for col in column_names} # 3. 使用自定义Schema扫描CSV并导出为Parquet ( pl.scan_csv( filename, separator="|", schema=forced_schema, # 强制应用全字符串类型的Schema type_coercion=False ) .sink_parquet( filename.replace(".txt", ".parquet"), compression="zstd", compression_level=11 ) )
关键步骤解释
- 高效获取列名:通过
n_rows=0参数扫描CSV,只会读取表头信息而不加载任何数据行,完全适配128G级别的超大文件,不会占用过多内存。 - 构建强制Schema:用字典推导式生成所有列对应
pl.Utf8(字符串)类型的Schema,Polars会严格按照这个配置解析每一列,彻底关闭自动类型推断。 - 懒加载处理与导出:依然使用
scan_csv的懒加载模式,处理过程全程内存友好,同时保留你原来的高压缩级别zstd配置,尽可能控制Parquet文件体积。
补充说明
- 关于文件体积变大:由于所有列都以字符串存储,Parquet针对数值/日期类型的紧凑存储优化无法生效,因此文件体积可能会暂时大于类型推断正确的情况。但这是可逆的——后续你可以针对特定列转换类型后重新导出,此时体积会明显缩小。
- 空值与异常值处理:文件中的空值或格式异常值会被保留为字符串类型的
None或原始文本,后续处理时可以通过str.to_numeric/str.to_date等方法灵活转换(无法转换的值可设为None):# 示例:将指定列转换为整数类型(不强制报错) processed_df = pl.scan_parquet("example.parquet").with_columns( pl.col("numeric_column").str.to_numeric(downcast=int, strict=False) ) processed_df.sink_parquet("processed_example.parquet", compression="zstd", compression_level=11) - 性能保障:全程基于Polars的懒执行引擎,不会将整个超大文件加载到内存,适合你的批量处理场景。
备注:内容来源于stack exchange,提问作者user1805103
相关产品推荐
相关产品推荐

