Polars DataFrame行与列表直接匹配过滤方法及报错解析
Polars列表匹配问题:报错原因与解决方案
场景复现
创建如下Polars DataFrame:
import polars df = polars.DataFrame(dict( j=[1,2,3], k=[4,5,6], l=[7,8,9], ))
DataFrame结构:
shape: (3, 3) ┌─────┬─────┬─────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 1 ┆ 4 ┆ 7 │ │ 2 ┆ 5 ┆ 8 │ │ 3 ┆ 6 ┆ 9 │ └─────┴─────┴─────┘
尝试的代码与报错
为适配可变列的DataFrame,尝试直接用列表匹配过滤行,代码如下:
df = df.filter( polars.concat_list(polars.all()) == [2, 5, 8] )
抛出错误:
exceptions.ArrowErrorException: NotYetImplemented("Casting from Int64 to LargeList(Field { name: \"item\", data_type: Int64, is_nullable: true, metadata: {} }) not supported")
报错原因
polars.concat_list(polars.all())会将每行的多列值合并为列表类型的列,但直接与Python原生列表[2,5,8]对比时,Polars会尝试将右侧列表转换为与左侧匹配的数据类型。当前Polars暂不支持将Int64类型转换为LargeList类型,因此触发这个未实现的转换错误。本质是左右两侧的类型匹配逻辑中,出现了Polars尚未支持的类型转换操作。
可行的列表匹配方法
1. 针对多普通列的DataFrame实现行转列表匹配
只需将右侧的Python列表用polars.lit()包装为Polars的列表常量,确保两侧类型一致即可:
# 方法1:使用concat_list df.filter(polars.concat_list(polars.all()) == polars.lit([2,5,8])) # 方法2:使用arr.to_list()更简洁 df.filter(polars.all().arr.to_list() == polars.lit([2,5,8]))
执行后会正确过滤出目标行:
shape: (1, 3) ┌─────┬─────┬─────┐ │ j ┆ k ┆ l │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 2 ┆ 5 ┆ 8 │ └─────┴─────┴─────┘
2. 针对本身含列表列的DataFrame匹配指定列表
如果DataFrame本身存储的是列表类型的列,直接用polars.lit()包装目标列表即可匹配,甚至可以直接使用Python列表(推荐用lit明确类型):
# 创建含列表列的DataFrame df_list = polars.DataFrame({"values": [[1,4,7], [2,5,8], [3,6,9]]}) # 方法1:用lit包装列表 df_list.filter(polars.col("values") == polars.lit([2,5,8])) # 方法2:直接使用Python列表(类型匹配时可正常工作) df_list.filter(polars.col("values") == [2,5,8])
执行后会得到目标行:
shape: (1, 1) ┌───────────┐ │ values │ │ --- │ │ list[i64] │ ╞═══════════╡ │ [2, 5, 8] │ └───────────┘
内容的提问来源于stack exchange,提问作者levant pied
相关产品推荐
相关产品推荐

