使用Polars读取Pandas保存的Parquet文件报错,求解决方案
解决Polars读取Pandas保存的Parquet分类列报错问题
问题重现
用Pandas 2.1.3保存带整数分类列的DataFrame为Parquet文件,再用Polars 0.19.19读取时触发报错:
import pandas as pd import polars as pl # Pandas保存Parquet test_df = pd.DataFrame({"a":[10,10,0,100,0]}) test_df["b"] = test_df.a.astype("category") test_df.to_parquet("test_df.parquet") # Polars读取报错 test_pl_df = pl.read_parquet("test_df.parquet")
报错信息:
polars.exceptions.ComputeError: only string-like values are supported in dictionaries
核心原因
Pandas默认用fastparquet引擎保存分类列时,会将整数类型的分类编码为Parquet字典类型(键为整数),而Polars 0.19.x版本对非字符串类型的字典支持有限,因此触发错误。
直接用Polars读取的解决方案
方案1:读取时禁用字典解析,再手动转分类类型
通过read_dictionary=False参数让Polars跳过字典类型解析,直接读取原始整数数据,之后再转换为Polars的Categorical类型:
# 直接读取,禁用字典解析 test_pl_df = pl.read_parquet("test_df.parquet", read_dictionary=False) # 转换为Polars分类类型 test_pl_df = test_pl_df.with_columns(pl.col("b").cast(pl.Categorical))
这个方法也支持懒加载的scan_parquet:
lazy_df = pl.scan_parquet("test_df.parquet", read_dictionary=False) lazy_df = lazy_df.with_columns(pl.col("b").cast(pl.Categorical)) # 触发计算 test_pl_df = lazy_df.collect()
方案2:调整Pandas保存方式,适配Polars读取
如果可以修改Pandas的保存逻辑,改用pyarrow引擎并指定dtype_backend="pyarrow",这样保存的Parquet文件会将分类列存储为Polars兼容的格式,无需额外处理即可直接读取:
# Pandas保存时改用pyarrow引擎 test_df.to_parquet("test_df.parquet", engine="pyarrow", dtype_backend="pyarrow") # Polars直接读取 test_pl_df = pl.read_parquet("test_df.parquet")
内容的提问来源于stack exchange,提问作者ivegotaquestion
相关产品推荐
相关产品推荐

