如何更Pythonic地拼接含pl.Enum类型列的Polars DataFrame?
Polars中合并含不同Enum取值的DataFrame的Pythonic方案
当两个结构一致的Polars DataFrame包含pl.Enum类型列,但该列的取值集合不同时,直接调用pl.concat()会触发SchemaError。除了手动转换为包含所有取值的Enum类型外,有两种更Pythonic的实现方式:
1. 自动合并Enum取值,生成统一类型后合并
先提取两个DataFrame中Enum列的所有取值,生成包含完整集合的新Enum类型,再转换两DataFrame的对应列后合并:
import polars as pl # 示例数据 df1 = pl.DataFrame({"status": pl.Series(["active", "inactive"], dtype=pl.Enum(["active", "inactive"]))}) df2 = pl.DataFrame({"status": pl.Series(["pending", "active"], dtype=pl.Enum(["pending", "active"]))}) # 获取所有Enum取值并生成统一类型 all_statuses = df1["status"].get_categories() | df2["status"].get_categories() unified_status_enum = pl.Enum(sorted(all_statuses)) # 转换列类型后合并 df_combined = pl.concat([ df1.with_columns(pl.col("status").cast(unified_status_enum)), df2.with_columns(pl.col("status").cast(unified_status_enum)) ])
这种方式的优势是显式控制Enum的取值顺序,适合需要严格规范类型的场景。
2. 利用pl.concat的schema参数直接指定统一类型
无需提前转换每个DataFrame,直接在合并时通过schema参数指定包含所有取值的Enum类型,一步完成合并:
import polars as pl # 示例数据同前 df1 = pl.DataFrame({"status": pl.Series(["active", "inactive"], dtype=pl.Enum(["active", "inactive"]))}) df2 = pl.DataFrame({"status": pl.Series(["pending", "active"], dtype=pl.Enum(["pending", "active"]))}) # 生成统一Enum类型 all_statuses = df1["status"].get_categories() | df2["status"].get_categories() unified_status_enum = pl.Enum(sorted(all_statuses)) # 直接合并并指定schema df_combined = pl.concat([df1, df2], schema={"status": unified_status_enum})
这种方式更简洁,减少了中间步骤,符合Pythonic的"简洁优先"原则。
补充:临时转为字符串类型合并(适合快速验证)
如果只是临时合并无需保留Enum类型,也可以先转为字符串再合并,后续按需转回Enum:
df_combined = pl.concat([ df1.with_columns(pl.col("status").cast(str)), df2.with_columns(pl.col("status").cast(str)) ]).with_columns(pl.col("status").cast(pl.Enum(sorted(df_combined["status"].unique()))))
内容的提问来源于stack exchange,提问作者Andi
相关产品推荐
相关产品推荐

