
Polars 的 with_columns 支持按数据类型(如 pl.String 或 pl.List(pl.String))筛选列并应用对应类型转换与哈希,避免错误 cast 导致全 null 或重复哈希值。
polars 的 `with_columns` 支持按数据类型(如 `pl.string` 或 `pl.list(pl.string)`)筛选列并应用对应类型转换与哈希,避免错误 cast 导致全 null 或重复哈希值。
在 Polars 中,直接对字符串列使用 pl.List(pl.Categorical) 进行 cast 是不合法的——这并非用户误用,而是类型系统严格校验的结果:当 pl.col("stris").cast(pl.List(pl.Categorical)) 作用于纯字符串列时,Polars 会静默返回全 null 的 list[u32],进而导致后续 .hash() 对所有行生成相同哈希值(因 hash 输入实为统一的 null 值)。你观察到的 stris_hashed 列全部为 594396677107 正是这一行为的典型表现。
✅ 正确做法是按列实际类型分别指定 cast 策略,而非强行统一 cast。Polars 提供了强大的类型感知表达式支持,可通过 pl.col(dtype) 精准匹配列:
import polars as pl
list_of_lists = [
['base', 'base.current base', 'base.current base.inventories - total', 'ABCD'],
['base', 'base.current base', 'base.current base.inventories - total', 'DEFG'],
['base', 'base.current base', 'base.current base.inventories - total', 'ABCD'],
['base', 'base.current base', 'base.current base.inventories - total', 'HIJK']
]
list_of_strings = ['(bobbyJoe460)', 'bobby, Joe (xx866e)', '137642039575', 'mamamia']
pl_df_1 = pl.DataFrame({'lists': list_of_lists, 'stris': list_of_strings})
# ✅ 按类型分别 cast + hash
result = pl_df_1.with_columns(
# 匹配 List(String) 类型列 → cast 为 List(Categorical) → hash
pl.col(pl.List(pl.String)).cast(pl.List(pl.Categorical)).hash(seed=140).name.suffix('_hashed'),
# 匹配 String 类型列 → cast 为 Categorical → hash
pl.col(pl.String).cast(pl.Categorical).hash(seed=140).name.suffix('_hashed')
)
print(result)输出中 stris_hashed 将呈现差异化哈希值,验证类型精准匹配的有效性。
? 进阶技巧:若列类型映射关系复杂或需复用,可封装为字典驱动的表达式生成器:
type_cast_map = {
pl.String: pl.Categorical,
pl.List(pl.String): pl.List(pl.Categorical),
}
expressions = [
pl.col(dtype).cast(target_type).hash(seed=140).name.suffix('_hashed')
for dtype, target_type in type_cast_map.items()
]
result = pl_df_1.with_columns(expressions)⚠️ 注意事项:
-
pl.col(pl.String)仅匹配物理类型为String的列(不含嵌套结构),而pl.col(pl.List(pl.String))严格匹配list[string];二者互斥,不会误匹配。 - 不要依赖
.cast(pl.List(...))处理非列表列——Polars 不会报错但会返回null,务必通过类型选择器前置过滤。 -
pl.Categorical在哈希前可提升性能(尤其对高基数字符串),但需确保内存充足(类别字典驻留内存)。
总结:Polars 的类型选择器(pl.col(dtype))是实现“条件 cast”的标准、安全且高效的方式,完全替代了手动判断类型的布尔逻辑需求——它本质是声明式类型路由,比运行时 if-else 更符合表达式编程范式,也更易维护与测试。

















